将栈顶top与头指针合二为一,不是和栈顶节点合二为一;
在建立链表的时候,由于栈的特性是先入后出,所以采用尾插法,将新节点放在头结点和前一新节点之间,top指向最后一个插入的节点;
#include <iostream>
using namespace std;
#define OK 1
#define ERROR 0
typedef int SElemType;
typedef int Status;
/* 链栈的结构定义
* 栈顶top与头指针合二为一,不是和栈顶节点合二为一
* top指向最后入栈的元素,所以头指针指向最后一个节点
*/
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
}StackNode,*LinkStackptr;
typedef struct LinkStack
{
LinkStackptr top;
int count; // 节点个数
}LinkStack;
/* 链栈的创建:CreatLinkStack
* 输入链栈的初始长度:length
* 将头指针作为top,头指针指向最后一个节点
* 创建头结点s1和新节点p,且要初始化
* 必须使用尾插法,将新节点放在头节点和前一新节点之间
*/
Status CreatLinkStack(LinkStack *S,int length)
{
int i;
SElemType j;
S->count = length;
LinkStackptr s1,p;
s1 = (LinkStackptr)malloc(sizeof(StackNode));
s1->next = NULL; // 表示最后一个节点的指向
cout << "输入链栈元素:";
for (i = 0; i < length; i++)
{
p = (LinkStackptr)malloc(sizeof(StackNode));
cin >> j;
p->data = j;
p->next = s1->next;
s1->next = p;
}
S->top=s1->next;
return OK;
}
/* 压栈操作:Push
* 思路:
* 1、链栈为S,新建一个节点p,并初始化(分配内存),数据域为e
* 2、节点p为新的栈顶
* 3、计算:p->next=S->top,S->top=p
* 4、节点个数+1
*/
Status Push(LinkStack *S, SElemType e)
{
LinkStackptr p;
p = (LinkStackptr)malloc(sizeof(StackNode));
p->data = e;
p->next = S->top;
S->top = p;
S->count++;
return OK;
}
/* 出栈操作:Pop
* 思路:
* 1、链栈为S,判断链栈是否为空:S->top==NULL
* 2、出栈元素返回为e
* 3、声明一个新节点p,用于存储top指向的节点
* 4、计算:p=S->top,e=S->top->data
* 5、释放第一个节点,计算:S->top=S->top->next;free(p)
* 6、节点数-1
*/
Status Pop(LinkStack *S, SElemType *e)
{
LinkStackptr p;
if (S->top == NULL)
{
cout << "链栈为空" << endl;
return ERROR;
}
*e = S->top->data;
p = S->top;
S->top = S->top->next;
free(p);
S->count--;
return OK;
}
int main()
{
int i,j,length;
SElemType e;
LinkStack *S;
S = (LinkStack *)malloc(sizeof(LinkStack));
cout << "链栈初始长度:";
cin >> length;
CreatLinkStack(S,length);
cout << "出栈元素个数:";
cin >> j;
cout << "部分出栈:";
for (i = 0; i < j; i++)
{
Pop(S, &e);
cout << e << ' ';
}
cout << endl;
cout << "链栈进栈元素为:";
cin >> e;
Push(S, e);
cout << "全部出栈:";
while (S->top != NULL)
{
Pop(S, &e);
cout << e << ' ';
}
cout << endl;
return OK;
}
结果为: