一,只有栈顶的情况。
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;
}