链栈,两种写法对比
两种写法的本质一样,但是写法上略有不同,个人认为两者之间的外部操作有着很大的区别(C语言初学者,如有描述错误,还请大佬指出)
第一种
(参考–>数据结构-浙江大学 陈姥姥)
只声明一个结构体,该结构体是结点的结构体,相当于,我们每次进行push和pop的时候都是直接对结点进行操作,并不是直接操作这个链栈
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef int ElemType;
typedef struct SNode
{
ElemType data;
SNode *next;
} SNode,*Stack;
Stack InitStack()
{
Stack S;
S = (Stack)malloc(sizeof(SNode));
S->next = NULL;
return S;
}
int IsEmpty(Stack S)
{
if(S->next == NULL)
return TRUE;
else
return FALSE;
}
void Push(Stack S,ElemType e)
{
Stack p;
p = (Stack)malloc(sizeof(SNode));
p->data = e;
p->next = S->next;
S->next = p;
}
ElemType Pop(Stack S,ElemType *e)
{
if(IsEmpty(S))
{
printf("栈为空\n");
*e = NULL;
return ERROR;
}
Stack p;
*e = S->next->data;
p = S->next;
S->next = p->next;
free(p);
return OK;
}
void GetTop(Stack S,ElemType *e)
{
if(S->next==NULL)
return ;
*e = S->next->data;
}
void ClearStack(Stack S)
{
Stack p,q;
while(S->next!=NULL)
{
p = S->next;
S->next = p->next;
free(p);
}
// ElemType e;
// while(S->next!=NULL)
// {
// Pop(S,&e);
// }
}
void StackTraverse(Stack S)
{
if(S->next==NULL)
{
printf("栈为空");
}
while(S->next!=NULL)
{
printf("%d ",S->next->data);
S = S->next;
}
printf("\n");
}
int main()
{
Stack S = InitStack();
printf("栈初始化……\n");
ElemType e;
printf("栈是否为空(1:YES 0:NO):%d\n",IsEmpty(S) ? 1:0);
printf("开始赋值操作######\n");
for(int i=1; i<=10; i++)
{
Push(S,i);
}
printf("栈中的元素为:");
StackTraverse(S);
printf("栈是否为空(1:YES 0:NO):%d\n",IsEmpty(S) ? 1:0);
GetTop(S,&e);
printf("栈顶元素是%d \n",e);
Pop(S,&e);
printf("弹出栈顶元素%d\n",e);
printf("栈中的元素是:");
StackTraverse(S);
// for(int i=0; i<9; i++)
// {
// Pop(S,&e);
// printf("弹出栈顶元素%d\n",e);
// }
// printf("栈是否为空(1:YES 0:NO):%d\n",IsEmpty(S) ? 1:0);
ClearStack(S);
printf("清空栈××××××\n");
printf("栈是否为空(1:YES 0:NO):%d\n",IsEmpty(S) ? 1:0);
printf("栈中的元素为:");
StackTraverse(S);
return 0;
}
第二种
(参考《大话数据结构》)
这里我们声明两个结构体,第一个结构体是结点结构体,第二个结构体是链栈的结构体用来直接表示出该链栈的top结点和长度,那么在这里,我们的push和pop操作是对链栈进行直接操作
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSiZE 20
typedef int Status;
typedef int SElemType;
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
} StackNode,*LinkStackPtr;
typedef struct
{
LinkStackPtr top;
int Count;
} LinkStack;
Status visit(SElemType e)
{
printf("%d ",e);
return OK;
}
Status InitStack(LinkStack *S)
{
S->top = (LinkStackPtr)malloc(sizeof(StackNode));
if(!S->top)
return ERROR;
S->top =NULL;
S->Count = 0;
return OK;
}
Status StackEmpty(LinkStack S)
{
if(S.Count==0)
return TRUE;
else
return FALSE;
}
Status ClearStack(LinkStack *S)
{
LinkStackPtr p,q;
p = S->top;
while(p)
{
q = p;
p = p->next;
free(q);
}
S->Count = 0;
return OK;
}
Status StackLength(LinkStack S)
{
return S.Count;
}
Status GetTop(LinkStack S,SElemType *e)
{
if(!S.top)
return ERROR;
else
*e = S.top->data;
return OK;
}
Status Push(LinkStack *S,SElemType e)
{
LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
p->data = e;
p->next = S->top;
S->top = p;
S->Count++;
return OK;
}
Status Pop(LinkStack *S,SElemType *e)
{
if(StackEmpty(*S)==TRUE)
return ERROR;
*e = S->top->data;
LinkStackPtr p;
p = S->top;
S->top = p->next;
free(p);
S->Count--;
return OK;
}
Status StackTraverse(LinkStack S)
{
LinkStackPtr p = S.top;
while(p)
{
visit(p->data);
p = p->next;
}
printf("\n");
return OK;
}
int main()
{
int j;
LinkStack s;
int e;
if(InitStack(&s)==OK)
for(j=1; j<=10; j++)
Push(&s,j);
printf("栈中元素依次为:");
StackTraverse(s);
Pop(&s,&e);
printf("弹出的栈顶元素 e=%d\n",e);
printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s));
GetTop(s,&e);
printf("栈顶元素 e=%d 栈的长度为%d\n",e,StackLength(s));
ClearStack(&s);
printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s));
return 0;
}