链栈的定义
链栈有两个区域,一个区域保存数据,另一个区域保存指针。
typedef struct LinkStack
{
int data;
struct LinkStack* next;
}Node, * St;
入栈操作
链栈可以看做一个采用头插法的单链表,因为在入栈时,元素始终插在队头。
插入后,将头指针修改为指向新插入的结点。
链栈不需要判断是否存储满,存就完事。这点令人舒适。
bool Push(St& S, int e)//链栈的入栈 就是 链表的头插法
{
Node* p = new Node;// 创建新结点 保存数据
p->data = e;
p->next = S;// 将新结点插在链栈的首部,S是已有结点,放在新结点之后
S = p;// 头指针指向p
return true;
}
出栈操作
bool Pop(St& S, int &e)
{
Node* q = S;// 保存要删除的结点
if (S)
{
e = S->data;
S = S->next;// 到最后一个结点时,S指向NULL
delete q;
cout << "元素" << e << "出栈\n";
return true;
}
return false;
}
取栈顶元素
过于简单不想讲。
当链栈不为空栈时,返回头指针当前指向的元素。
int GetTop(St& S)
{
if (S)
return S->data;
return 0;
}
完整代码
虽然实现很简单,还是建议自己写一遍,有助于真正掌握。
#include <iostream>
using namespace std;
typedef struct LinkStack
{
int data;
struct LinkStack* next;
}Node, * St;
void Init(St& S)// 不需要设头结点
{
S = NULL;// 初始栈为空
printf("初始化成功\n");
}
bool Push(St& S, int e)//链栈的入栈 就是 链表的头插法
{
Node* p = new Node;// 创建新结点 保存数据
p->data = e;
p->next = S;// 将新结点插在链栈的首部,S是已有结点,放在新结点之后
S = p;// 头指针指向p
cout << "元素" << e << "入栈\n";
return true;
}
bool Pop(St& S, int &e)
{
Node* q = S;// 保存要删除的结点
if (S)
{
e = S->data;
S = S->next;// 到最后一个结点时,S指向NULL
delete q;
cout << "元素" << e << "出栈\n";
return true;
}
return false;
}
int GetTop(St& S)
{
if (S)
return S->data;
return 0;
}
int main()
{
St S;
Init(S);
int code;
int e;
do
{
printf("请输入操作码 0-退出系统 1-入栈 2-出栈 3-取栈顶元素\n");
cin >> code;
switch (code)
{
case 1:
cout << "请输入入栈元素 输入-1退出入栈操作";
cin >> e;
while (e != -1)
{
Push(S, e);
cin >> e;
}
break;
case 2:
if (!Pop(S, e))
cout << "栈为空\n";
break;
case 3:
cout << "栈顶元素为" << GetTop(S) << "\n";
break;
}
} while (code != 0);
return 0;
}