栈的链式存储——链栈
链栈似乎和单链表有着不可告人的“血缘”关系,想一想都是线性结构,关系是摆脱不鸟的;先看一个来自《大话数据结构》一书中的一图:
让咋们把头向右旋转 90° (不要维持太久),是不是惊讶到不就是抛弃了头节点的单链表吗!那么,这关系是不是很明显了。
不过为了方便链栈定义的结构体在单链表上的定义做了改动,改动后如下
typedef char ElemType;
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}StackNode, *LinkStackNode;
typedef struct LinkStack
{
LinkStackNode top; //'top' is stack top pointer(栈的指针)
int Count; //'Count' is number of elements of the stack(栈元素的个数)
}LinkStack;
其实我当初的疑惑是定义 top 的原因,个人认为这个 top 是为了跟方便地对栈进行操作。
接下来看一下链栈的进出栈的草图
代码
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct StackNode
{
ElemType data;
struct StackNode *next;
}StackNode, *LinkStackNode;
typedef struct LinkStack
{
LinkStackNode top; //'top' is stack top pointer(栈的指针)
int Count; //'Count' is number of elements of the stack(栈元素的个数)
}LinkStack;
void Init_Stack(LinkStack *S)
{
S->top = NULL;
S->Count = 0;
}
void push_Stack(LinkStack *S, ElemType e)
{
LinkStackNode sNew = (LinkStackNode)malloc(sizeof(StackNode));
sNew->data = e;
sNew->next = S->top;
S->top = sNew;
S->Count++;
}
void traver_Stack(LinkStack S)
{
LinkStackNode p = S.top;
if (p != NULL)
{
while(p != NULL)
{
printf("%c ", p->data);
p = p->next;
}
printf("\n");
}
else
{
printf("The stack is empty!!\n");
}
}
bool pop_Stack(LinkStack *S, ElemType *e)
{
LinkStackNode p = S->top;
if (p == NULL)
{
return false;
}
*e = p->data;
S->top = p->next;
free(p);
S->Count--;
return true;
}
bool clear_Stack(LinkStack *S)
{
if (S->top == NULL)
{
return true;
}
LinkStackNode p;
LinkStackNode q;
p = S->top;
while(p)
{
q = p->next;
free(p);
p = q;
}
S->top = NULL;
S->Count = 0;
return true;
}
int main()
{
LinkStack S;
ElemType e;
Init_Stack(&S); //Initialization the stack
int option = 1;
printf("\n 1. Initialization stack; \n 2. Push stack;\n 3. Traversing stack; \n 4. Pop stack; \n 5. Clear stack; \n 0. Exit\n");
while(option)
{
printf("Please operate on the stack: ");
scanf("%d", &option);
// scanf("%*[^\n]%*c");
switch(option)
{
case 1:
Init_Stack(&S);
break;
case 2:
printf("Please enter the value to be pushed stack: ");
getchar();
scanf("%c", &e);
push_Stack(&S, e); //Element stack(元素入栈)
break;
case 3:
traver_Stack(S);
break;
case 4:
getchar();
if (pop_Stack(&S, &e))
{
printf("The element of poping stack is %c \n", e);
}
else
{
printf("Poping stack is fail ! \n");
}
break;
case 5:
if(clear_Stack(&S))
{
printf("Stack has been cleared!!\n");
}
case 0:
exit(0);
default:
printf("Incorrect operation! Please re-operate!\n");
break;
}
scanf("%*[^\n]%*c");
option = 9;
}
return 0;
}