C++ 链栈

总结归纳

  1. 我想了又想,觉得链栈的实现只能是头插法建立单链表,S 为头结点,S-next->data 是栈顶元素,S->next 是栈顶指针,每次弹出就是通过头结点找到栈顶元素,再将栈顶指针后移,其实就是单链表里实现的那一套。其他的形式我实在是写不出来,如果有可以在评论区告诉我,感激不尽。
  2. 这里为链栈设置了头结点,代码写起来更方便。对于不设置头结点的链栈,我认为也能实现,毕竟都有不带头结点的单链表,这单链表和链栈简直是一家子。
  3. 在访问变量过程中,对 “.” 和 “->” 的使用产生了疑问,经过查询,我认为:当访问直接对象的成员或数据时,使用 “.” 进行访问;当访问地址(指针或迭代器)的成员或数据时,使用 “->” 访问。
// 结点结构体
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表示表尾
}
  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;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值