栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。
- 链式栈无栈满问题,空间可扩充
- 插入与删除仅在栈顶处执行
- 链式栈的栈顶在链头
- 适合于多栈操作
/* 链栈结构 */
typedef struct StackNode
{
SElemType data; //节点数据域
struct StackNode *next; //节点指针域
} StackNode,*LinkStackPtr; //节点指针
typedef struct LinkStack
{
LinkStackPtr top; //栈顶指针
int count; //栈中元素个数
}LinkStack;
//栈的初始化操作
Status InitStack(LinkStack &S)
{
S.top = (LinkStackPtr)malloc(sizeof(StackNode));
if(!S.top)
return ERROR;
S.top->next = NULL;
S.count = 0;
return OK;
}
/* 把S置为空栈 */
Status ClearStack(LinkStack &S)
{
LinkStackPtr p, q;
p = S.top->next;
while(p)
{
q = p;
p = p->next;
free(q);
}
S.count=0;
return OK;
}
/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
Status IsEmptyStack(LinkStack S)
{
if (S.count == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
Status GetTopElem(LinkStack S,SElemType *e)
{
if (S.top->next == NULL)
{
return ERROR;
}
else
{
*e = S.top->next->data;
}
return OK;
}
/* 压栈 */
Status Push(LinkStack &S, SElemType e)
{
LinkStackPtr p=(LinkStackPtr)malloc(sizeof(StackNode));
if (!s)
{
return ERROR;
}
p->data = e;
p->next = S.top->next ;
S.top->next = p;
S.count++;
return OK;
}
/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(LinkStack &S,SElemType &e)
{
LinkStackPtr p;
if(IsEmptyStack(S))
{
return ERROR;
}
p = S.top->next;
e = p->data;
S.top->next = p->next;
free(p);
S.count--;
return OK;
}
附录:完整代码调试
#include <iostream>
using namespace std;
typedef int SElemType;
typedef int Status;
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
} StackNode, *LinkStackPtr;
typedef struct LinkStack
{
LinkStackPtr top;
int count;
}LinkStack;
Status InitStack(LinkStack &S)
{
S.top=(LinkStackPtr)malloc(sizeof(StackNode));
if(!S.top) return -1;
S.top->next=NULL;
S.count=0;
return 1;
}
Status ClearStack(LinkStack &S)
{
LinkStackPtr p,q;
p = S.top->next;
while(p)
{
q=p;
p=p->next;
S.top->next=p;
free(q);
}
S.count=0; //
return 1;
}
bool IsEmptyStack(LinkStack S)
{
if(S.top->next==NULL) return true;
return false;
}
Status GetTopElem(LinkStack S,SElemType *e)
{
LinkStackPtr p;
p=S.top->next;
if(!p) *e=0;
else *e=p->data; // *e
return 1;
}
Status Push(LinkStack &S,SElemType e) //如果是*S 的话下面要用S->top->next
{
LinkStackPtr P;
P=(LinkStackPtr)malloc(sizeof(StackNode));
P->data=e;
P->next=S.top->next;
S.top->next=P;
S.count++; //
return 1;
}
Status Pop(LinkStack &S,SElemType &e)
{
LinkStackPtr p;
if(IsEmptyStack(S)) return 0;
p = S.top->next;
e=p->data;
S.top->next=p->next;
free(p); //
S.count--;
return e;
}
void menu()
{
cout<<"初始化栈:0"<<endl;
cout<<"入栈:1"<<endl;
cout<<"出栈:2"<<endl;
cout<<"取栈顶元素:3"<<endl;
cout<<"清空栈:4"<<endl;
cout<<"退出:5"<<endl;
}
int main()
{
LinkStack S;
while(true)
{
menu();
int n;
scanf("%d",&n);
switch(n)
{
int x;
case 0:
if(InitStack(S)) printf("\n初始化成功\n\n");
continue;
case 1:
cout<<"输入一个元素"<<endl;
cin>>x;
Push(S,x);
continue;
case 2:
x=Pop(S,x);
printf("删除%d\n",x);
continue;
case 3:
GetTopElem(S,&x);
printf("栈顶元素是%d\n",x);
continue;
case 4:
ClearStack(S);
printf("\n栈已清空\n");
continue;
default:
break;
}
if(n==5) break;
}
return 0;
}