总结归纳
- 我想了又想,觉得链栈的实现只能是头插法建立单链表,S 为头结点,S-next->data 是栈顶元素,S->next 是栈顶指针,每次弹出就是通过头结点找到栈顶元素,再将栈顶指针后移,其实就是单链表里实现的那一套。其他的形式我实在是写不出来,如果有可以在评论区告诉我,感激不尽。
- 这里为链栈设置了头结点,代码写起来更方便。对于不设置头结点的链栈,我认为也能实现,毕竟都有不带头结点的单链表,这单链表和链栈简直是一家子。
- 在访问变量过程中,对 “.” 和 “->” 的使用产生了疑问,经过查询,我认为:当访问直接对象的成员或数据时,使用 “.” 进行访问;当访问地址(指针或迭代器)的成员或数据时,使用 “->” 访问。
// 结点结构体
struct LinkNode {
ElemType data;
LinkNode *next;
};
void Test1(LinkNode S, ElemType e){
S.data = e; // 传入结点S,属于直接访问
}
void Test2(LinkNode *S, ElemType e){
S->data = e; // 传入指针,指针为变量,存储目标对象的地址,使用 —>
}
void Test3(LinkNode &S, ElemType e){
S.data = e; // 引用传递,即传递的是实体本身,同样属于直接访问
}
关于代码实现,由于我将结点指针重定义为 LiStack:
typedef LinkNode *LiStack;
所以在函数的传参中,LiStack S 实际就是 LinkNode* S,仍然是指针传参,所以变量的访问自然用 “->” 。
与此形成对比的是静态链表,传入的是数组本身,不论是初始化还是赋值,访问的都是本身,所以使用 “.” 进行访问:
struct Node {
int data;
int next;
};
typedef Node SLinkList[MaxSize]; // 用SLinkList定义一个长度为MaxSize的Node型数组
// 初始化静态链表
void InitList(SLinkList &L) {
for (int i = 0; i < MaxSize; i++) {
L[i].data = 0;
L[i].next = -2; // 清除脏数据
}
L[0].next = -1; // -1表示表尾
}
- 关于代码有个疑问,例如函数 bool Push(LiStack &S, ElemType e) 中,不论我加不加 & ,对代码结果并没有影响,类似的还有很多,我并不了解这里的原因,如果有了解的麻烦在评论区留言。
代码实现
/*
链栈
*/
#include <iostream>
#include <string>
using namespace std;
typedef int ElemType;
// 结点结构体
struct LinkNode {
ElemType data;
LinkNode *next;
};
typedef LinkNode *LiStack; // 将结点重名名为链栈,代码更直观
// 初始化链栈,返回链栈
LiStack InitStack(LiStack &S) {
// S.top = (LinkNode *)malloc(sizeof(LinkNode)); // top为对象S的成员,通过 .
// 调用,当访问地址(指针)的成员时,通过 -> 调用
S = new LinkNode;
S->next = NULL;
return S;
}
// 判断链栈是否为空
bool StackEmpty(LiStack S) {
if (S->next == NULL) {
return true;
} else {
return false;
}
}
// 入栈
bool Push(LiStack &S, ElemType e) {
// LinkNode *p = (LinkNode*)malloc(sizeof(LinkNode));
LinkNode *p = new LinkNode;
p->data = e;
p->next = S->next;
S->next = p; // 更新栈顶指针
return true;
}
// 出栈
bool Pop(LiStack &S, ElemType &e) {
e = S->next->data;
LinkNode *r = new LinkNode;
r = S->next; // r指向栈顶
S->next = r->next; // 更新栈顶指针
delete r;
return true;
}
// 读取栈顶元素
bool GetTop(LiStack S, ElemType &x) {
if (S->next == NULL) {
return false;
} else {
x = S->next->data;
return true;
}
}
// 获取链栈长度
int GetLength(LiStack S) {
int i = 0;
LinkNode *r = new LinkNode;
r = S->next; // 指向栈顶
while (r != NULL) {
i++;
r = r->next; // 栈顶指针后移
}
delete r;
return i;
}
int main() {
LiStack S;
S = InitStack(S);
cout << "链栈是否为空:" << StackEmpty(S) << endl;
ElemType top, length,pop;
for (int i = 0; i < 5; i++) {
Push(S, i);
}
length = GetLength(S);
cout << "链栈长度:" << length << endl;
GetTop(S, top);
cout << "栈顶元素:" << top << endl;
Pop(S, pop);
GetTop(S, top);
cout << "新栈顶元素:" << top << endl;
length = GetLength(S);
cout << "新链栈长度:" << length << endl;
}