資料結構--c實現棧的出棧入棧
一,只有棧頂的情況。
1,首先定義連結串列單節點:
typedef struct node
{
ElementType data;
struct node *next
}StackNode ,*LinkStack;
2. 然後初始化,也就是給棧頂節點的元素賦值NULL 。
void InitStack(LinkStack top)
{
top->next = NULL;
}
這時候棧頂的連結串列節點如下:
3. 入棧
BOOL Push(LinkStack top,ElementType element)
{
StackNode *temp;
temp=(StackNode*)malloc(sizeof(StackNode));
if (temp==NULL)
{
return FALSE;
}
temp->data=element;
temp->next=top->next;
top->next=temp;
return TRUE;
}
- 執行完一次入棧:
- 先malloc temp1單節點,
temp=(StackNode*)malloc(sizeof(StackNode));
- 然後把num放入temp1的data。
temp->data=element;
- 然後讓temp節點的next 指向top原來指向的位置。
temp->next=top->next;
- 然後更換頭結點的next 指向為temp1的位置
top->next=temp;
在棧區資料儲存形式如下:
可以看到,top的next 指向了 temp1,然後,temp1的next 指向了NULL。NULL相當於棧底部。
- 如果再執行一次入棧,
- 又會malloc temp2 單節點。這時候,num2存入新malloc 的temp2的data元素中。
- 然後把top原來的指向位置也就是temp1的位置,賦值給temp2的指向,這時就變成了temp2的next 指向temp1。
- 然後將top的指向更換到temp2的位置,這時候,top的下面不再是temp1,而是插入了temp2.
整理下上面的圖,把temp2 插到top跟temp1之間,就是如下形式:
再往後,繼續push入棧,temp3就插入到temp2根棧頂top 之間,temp(n) 插入到temp(n-1)跟top之間。。。
4,出棧
接著看上面的temp2 開始看。
//出棧
BOOL Pop(LinkStack top,ElementType *element)
{
if (IsEmpty(top))
{
return FALSE;
}
StackNode *temp=top->next;
*element = temp->data;
top->next = temp->next;
free(temp);
temp=NULL;
return TRUE;
}
先要判斷下top是否為空,為空,就找不到temp2了。
if (IsEmpty(top))
{
return FALSE;
}
然後根據top的next 找到temp2,取出temp2內的data 元素,
StackNode *temp=top->next;
*element = temp->data;
然後把temp2的next 指向(temp1的位置)賦值給top的next 指向,為後面刪除temp2 做準備,這樣就不會把temp1給弄丟了。
top->next = temp->next;
接著就可以放心刪除temp2 了
free(temp);
temp=NULL;
這是,棧區的儲存形式就又回到了入棧temp1的狀態:
出棧比較簡單,分析完畢。
下面是完整程式。
#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
typedef int ElementType;
#define TRUE 1
#define FALSE 0
#define STACK_SIZE 100
typedef struct node
{
ElementType data;
struct node *next
}StackNode ,*LinkStack;
//初始化
void InitStack(LinkStack top)
{
top->next = NULL;
}
//是否為空
BOOL IsEmpty(LinkStack top)
{
if (top->next ==NULL)
{
return TRUE;
}else
{
return FALSE;
}
}
//入棧
BOOL Push(LinkStack top,ElementType element)
{
StackNode *temp;
temp=(StackNode*)malloc(sizeof(StackNode));
if (temp==NULL)
{
return FALSE;
}
temp->data=element;
temp->next=top->next;
top->next=temp;
return TRUE;
}
//出棧
BOOL Pop(LinkStack top,ElementType *element)
{
if (IsEmpty(top))
{
return FALSE;
}
StackNode *temp=top->next;
*element = temp->data;
top->next = temp->next;
free(temp);
temp=NULL;
return TRUE;
}
void InvertedSequence(int num)
{
int i=0;
int result =0;
LinkStack top;
top =(LinkStack)malloc(sizeof(StackNode));
InitStack(top);
printf("資料輸入為:\n");
for(int i=0;i<num;i++)
{
//入棧
Push(top, i);
printf("%d",i);
}
printf("\n資料輸出為:\n");
while(!IsEmpty(top))
{
//出棧
Pop(top,&result);
printf("%d",result);
}
printf("\n");
}
int main()
{
//printf("Hello world!\n");
int num=20;
InvertedSequence(num);
return 0;
}
二,同時又棧頂跟棧底的情況
具體就不詳細分析了,跟上面差不多。
差別在於,將棧頂,棧底,重新用一個結構體包起來,並初始化時,將棧底跟棧頂指向同一塊記憶體區域。
typedef struct node
{
ElementType data;
struct node *next;
}Node,*pNode;
typedef struct stack
{
pNode top;
pNode bottom;
}Stack,*pStack;
BOOL InitStack(pStack ps)
{
if (ps==NULL)
{
return FALSE;
}
ps->top=(pNode)malloc(sizeof(Node));
if (ps->top==NULL)
{
return FALSE;
}
ps->bottom=ps->top; //棧頂,跟棧底都指向同一記憶體塊。
ps->top->next=NULL;
return TRUE;
}
其實這裡棧底基本沒什麼用
詳細code 如下:
#include <stdio.h>
#include <stdlib.h>
typedef int BOOL;
typedef int ElementType;
#define STACK_SIZE 100
#define TRUE 1
#define FALSE 0
typedef struct node
{
ElementType data;
struct node *next;
}Node,*pNode;
typedef struct stack
{
pNode top;
pNode bottom;
}Stack,*pStack;
BOOL InitStack(pStack ps)
{
if (ps==NULL)
{
return FALSE;
}
ps->top=(pNode)malloc(sizeof(Node));
if (ps->top==NULL)
{
return FALSE;
}
ps->bottom=ps->top; //棧頂,跟棧底都指向同一記憶體塊。
ps->top->next=NULL;
return TRUE;
}
BOOL Push(pStack ps,ElementType num)
{
Node *temp=(Node*) malloc(sizeof(Node));//定義新節點,分配記憶體空間
if (temp==NULL)
{
return FALSE;
}
temp->data=num;
temp->next=ps->top;//讓新節點指向棧頂
ps->top=temp;//讓新節點成為棧頂,並新棧頂指向的是舊棧頂
return TRUE;
}
BOOL Pop(pStack ps,ElementType *num)
{
if(ps->top->next==NULL)
{
return FALSE;
}
pNode temp = ps->top;//先取出top 節點
*num = temp->data;//從top節點中取出元素data
ps->top = temp->next;//top節點修改,更改棧頂為top的下一個節點
free(temp);
temp=NULL;
return TRUE;
}
void InvertedSequence(int num)
{
int result =0;
pStack ps =(pStack)malloc(sizeof(Stack));
InitStack(ps);
printf("入棧開始\n");
for (int i=0;i<num;i++)
{
Push(ps,i);
printf("%d\t",i);
}
printf("\n出棧開始:\n");
while((ps->top)!=ps->bottom)
{
Pop(ps,&result);
printf("%d\t",result);
}
}
int main()
{
int num =10;
InvertedSequence(num);
return 0;
}