栈的简介

顺序存储的栈

	首先我们简单了解下什么是栈,做个比喻,把书堆叠起来,然后再拿走就是栈的特点:
后进先出(Last In First Out),并且只能再栈顶进行操作(添加或删除)。

话不多说,上代码:

栈的结构

struct Stack {
	int top;
	string* data;
}

简单加几个功能看看

const int MAX = 10;
struct Stack {
	int top;
	string* data;
	
	Stack() :top(0) { data = new string[MAX]; }

	void push(string s);
	void pop();
	void show();
	int count();
};

top 即指向栈顶,data为存储数据的数组;若要进行某些操作,只能通过控制top下标进行。

栈的基本操作

void Stack::push(string s) {
	if (top == MAX - 1)	return;
	data[top++] = s;
}

void Stack::pop() {
	if (top == 0)	return;
	top--;
}

看完发现,操作起来挺简单;实际上就是用数组体现出栈的特点,然后进行封装。C++语言中有一个头文件,就封装了栈Stack;

#include <stack>
stack<int> st;
st.push();
st.pop();

这样,基本的栈操作也能理解了。尽管stack库实际上的栈并非以顺序存储方式对栈进行封装,但这并不妨碍我们理解和使用栈stack;

两栈公用空间

		两栈共享空间,顾名思义,一个空间,给两个栈用。
	在代码上,如何体现呢? 实际上就是一个数组有俩“指针”,一个指向头,
一个指向尾;大概可以如下图理解:

结构

struct DoubleStack {
	string* data;
	int top1;
	int top2;
}

在这里插入图片描述

基本操作

struct DoubleStack {
	string* data;
	int top1;
	int top2;

	DoubleStack() :top1(-1), top2(MAX_SIZE) { data = new string[MAX_SIZE]; }

	void push(string s, int e) {
		if (top1 + 1 == top2)	return;

		if (e == 1)
			data[++top1] = s;

		else
			data[--top2] = s;
	}

	void pop(int e) {	//e表选择栈1还是栈2进行该操作
		if (top1 < -1 || top2 > MAX_SIZE)	return;

		if (e == 1)
			top1--;
		else
			top2++;

	}

	void show(int e) {
		if (e == 1) {	//根据各个栈的边界条件进行相应遍历
			for (int i = top1; i >= 0; --i)
				cout << data[i] << endl;
		}
		else {
			for (int i = top2; i < MAX_SIZE; ++i)
				cout << data[i] << endl;
		}
	}
};

实际上就是多操作了一个指针,他们的“极限”你可以想象是趋向中间;
毕竟top1向右增长,top2向左;两个栈相向增长,反向减少;所以按照普通的栈建造即可;
需要多注意一下“满栈”的边界条件是:top1+1==top2
“空栈”的边界条件是:top1<0 和 top2>MAX_SIZE-1(数组最大长度)
以及在push 和 pop函数中需要多指明一下在哪个栈进行操作。

双栈公用空间这种结构适用于同类型数据,数据存储呈现反向关系的类型;
你看,栈1占有更多空间,栈2空间就少了;

链栈

同顺序存储对应的就是链式存储结构,链表和数组的存储模式相应。
下面看看在链表形式的栈的模样吧!

链栈的结构


struct Node {
	string data;
	Node* next;
};

struct LinkStack {
	Node data;
	Node* top;
}

像链表一样的构造,然后给这个链表栈的特征,就是链栈了。
(后进先出,仅一个操作端,直接将头结点作top栈顶即可)

链栈的基本操作

struct LinkStack {
	Node data;
	Node* top;
	LinkStack() :data(), top(nullptr) {}
	void LS_create();
	void push(string s);
	void pop();
	void show();
};

栈初始化:

void LinkStack::LS_create() {
	top = nullptr;
}

添加元素:

void LinkStack::push(string s) {
	Node* p = new Node();
	p->data = s;
	p->next = top;		

	top = p;
}

删除元素:

void LinkStack::pop() {
	if (top == nullptr)	return;
	Node* p = top->next;
	delete top;
	top = p;
}

实际上,这栈这一片大多都是使用链表的思想,前期链表打好基础,后面的栈又或是队列都是将链表“特殊化”,给予一个特征,反而比单纯的链表更容易编写一些;虽然在运用栈的时候大多不会再去整一个,花个时间自己重现一次程序,运行一下,还是能够快速掌握的。



参考: 程杰老师的《大话数据结构》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值