数据结构-链栈详解(很朴实的那种)

链栈的设计与运行

1.链栈

提起链栈,很容易就想到单链表,不过链栈确实可以看做是受限的单链表,因为只能在链表头部进行操作,所以在链栈中也不再附加头结点,栈顶指针就是链表的头指针。
在这里插入图片描述
老话一句,实践一遍,万物皆好,下边的部分你要是懂了不妨照着葫芦画个瓢吧。

2.代码部分

  1. 主函数(和上一篇文章结构一样,本文如果哪里不懂可参考上一篇数据结构-顺序栈详解(超基础的那种)
#include"basic.h"

int main()
{
	int choose = -1;
	SElemType e;		//定义一个结构体的元素e
	InitStack(S);		//初始化顺序栈
	cout << "本次服务共有以下内容:" << endl << endl;
	cout << "1. 链栈的初始化" << endl;
	cout << "2. 判断栈是否为空" << endl;
	cout << "3. 链栈进栈" << endl;
	cout << "4. 链栈出栈" << endl;
	cout << "5. 取栈顶元素" << endl;
	cout << "0. 退出" << endl << endl;

	while (choose != 0) {

		cout << "请选择您需要的服务:" << endl;		//输入选择
		do {
			cin >> choose;
			if (choose < 0 || choose>5)
				cout << "您输入的信息不在本次服务之内,请重新输入:" << endl;
		} while (choose < 0 || choose>5);
		switch (choose)

		{
		case 1:
			InitStack(S);
				cout << "顺序栈初始化成功!" << endl << endl;
			break;
		case 2:
			if (StackEmpty(S))	cout << "此顺序栈为空!" << endl << endl;
			else cout << "此顺序栈不为空!" << endl << endl;
			break;
		case 3:
			cout << "请依次输入姓名和学号" << endl;
			cin >> e.name >> e.mumber;
			if (Push(S, e))	cout << "该元素入栈成功" << endl << endl;
			break;
		case 4:
			Pop(S, e);
			cout << "您本次取出的元素为:" << endl;
			cout << e.name << "  " << e.mumber << endl << endl;
			break;
		case 5:
			e=GetTop(S);
			cout << "您此时栈顶的元素为:" << endl;
			cout << e.name << "  " << e.mumber << endl << endl;
			break;
		default:break;
		}
	}
	return 0;
}
  1. basic.h头文件(这里只写出了基本功能)
#pragma once
#include<iostream>
using namespace std;
#define OVERFLOR -2
#define OK 1
#define ERROR 0
typedef int Status;		//表示状态

typedef struct		//定义一个的结构体
{
	char name[30];		//姓名
	char mumber[30];		//学号
}SElemType;

typedef struct StackNode
{
	SElemType data;
	struct StackNode* next;		//定义一个栈指针next
}StackNode,*LinkStack;		//定义一个栈指针类LinkStack

LinkStack S;	//定义一个栈顶指针

void InitStack(LinkStack& S)		//链栈的初始化
{
	S = NULL;
}

Status StackEmpty(LinkStack S)		//判断栈是否为空
{
	if (S == NULL) return OK;
	else return ERROR;
}

Status Push(LinkStack &S, SElemType &e)		//链栈进栈
{
	LinkStack P;
	P = new StackNode;
	if (!P) exit(OVERFLOR);		//判断是否成功创建新节点
	P->data = e;
	P->next = S;
	S = P;		//三步压进一个数
	return OK;
}

Status Pop(LinkStack& S, SElemType& e)		//链栈出栈
{
	LinkStack P;
	if (S == NULL) return ERROR;
	P = S;		//为了删除一个节点,引入P
	e = S->data;
	S = S->next;
	delete P;
	return 0;
}

SElemType GetTop(LinkStack S)		//取栈顶元素(尽量减小接口的复杂度)
{
	if (S == NULL) cout<<"此栈已空,无法取出栈顶元素"<<endl<<endl;
	else return S->data;
}

3. 代码分析

  1. 要注意exit(OVERFLOR)与return ERROR的区别,虽然都是报错,但前者是表示位置不够溢出了的错误,后者是因为找不到等原因的错误,当把错误具体划分后对以后构建更复杂的项目很有帮助。
  2. 难点集中在链栈进栈和出栈上,这里都新建了一个栈指针P,
  • 对于进栈来说流程是:构建一个新的节点;给新的节点赋值;栈顶指针指向新的节点;
  • 对于出栈来说流程是:取出栈顶指针的值;栈顶指针下移;(当然,我这里为了删除原位置,引用新节点指针,最后再一个delete)

4. 运行结果

在这里插入图片描述
今天的笔记就做到这里,下一篇打算写链栈对进制转换问题的求解。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值