5

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++

 1 year ago
source link: https://blog.51cto.com/zhangzhichaoya/6024031
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_数据结构

第十章 堆栈


第十章 堆栈

●一、堆栈是什么?

1.简要介绍

●二、堆栈操作的关键代码段

1.类型定义

2.顺序栈的常用操作

3.链式栈的常用操作


简单来说,数据结构是一种辅助程序设计并且进行优化的方法论,它不仅讨论数据的存储与处理的方法,同时也考虑到了数据彼此之间的关系与运算,从而极大程度的提高程序执行的效率,减少对内存空间的占用等。不同种类的数据结构适用于不同的程序应用,选择合适正确的数据结构,可以让算法发挥出更大的性能,给设计的程序带来更高效率的算法。


一、堆栈是什么?

1.简要介绍

堆栈是一组相同的数据类型的组合,所有的操作均在堆栈的顶端去进行,具有后进先出的特性。它是一种抽象的数据结构,具有两个显著特性:①只能从栈顶去进行存取数据的操作;②数据的存取符合后进先出的原则;栈它可以分为顺序栈和链式栈两种类型,它们在不同的问题中都会有广泛的应用。要特别注意链式栈指针域的指针指向,它与基本的链表有一定的差异。两种数据结构的类型如下图所示:

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_02

二、堆栈操作的关键代码段

1.类型定义

①顺序栈存储结构的定义

typedef struct {
	selemtype* base;    //栈底指针
	selemtype* top;    //栈顶指针
	int stacksize;		//堆栈大小
}sqstack;

②链式栈存储结构的定义

typedef struct stacknode{
	selemtype data;  //数据元素
	struct stacknode* next;  //指针域
}stacknode,*linklist;
linklist s;   //指针

2.顺序栈的常用操作

①顺序栈的初始化

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_03
void initstack(sqstack& s)
{
	s.base = new selemtype[maxsize];   //开拓一块新的堆栈区域,大小需要事先声明,并且将栈底指针指向栈底
	if (!s.base) {
		exit(0);  
	}   //创建失败
	else {
		s.top = s.base;   
		s.stacksize = maxsize;
	}   //创建成功,初始时需要将栈底指针的位置赋给栈顶指针,给栈一个空间大小
}

②判断顺序栈是否为空

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_C++_04
bool emptystack(sqstack& s)
{
	if (s.base == s.top) {
		return true;
	}   //如果栈底指针和栈顶指针指向同一个位置的话,也就是初始化下的状态时,就是空的
	else {
		return false;
	}    //反之不为空
}

③ 求顺序栈的长度

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_05
int lengthstack(sqstack& s)
{
	int length = s.top - s.base;  //头指针所在的位置减去尾指针所在的位置
	return length;
}

④ 清空顺序栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_06
void clearstack(sqstack& s)
{
	if (s.base)
		s.top = s.base;  
	//判断如果栈底指针存在,那么直接将栈底的位置赋到栈顶指针的位置即可,就好比初始化下的状态
}

⑤ 销毁顺序栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_数据结构_07
void destorystack(sqstack& s)
{
	if (s.base)
	{
		delete s.base;   
		s.stacksize = 0;  
		s.base = s.top = NULL;   //最终两个指针指向一块空的区域
	}
	//判断如果栈底指针存在,那么就说明这个栈存在,然后将栈底指针指向的那块删除,栈的长度直接修改为0即可
}

⑥顺序栈的入栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_算法_08
int pushstack(sqstack& s,selemtype e)
{
	if (s.top-s.base<s.stacksize) {   //如果此刻栈中元素的长度小于我们栈的总长度,那么说明可以继续入栈
		*s.top = e;   //将新数据入栈到栈顶
		s.top++;   //将栈顶指针向上移动
		return 1;
	}
	else {
		return 0;
	}
}

⑦顺序栈的出栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_算法_09
int popstack(sqstack& s, selemtype e)
{
	if (s.base == s.top) {   //空栈
		return 0;
	}
	else {
		s.top--;   //将栈顶指针向下移动
		e = *s.top;  //将出栈元素的数据内容保存
		return 1;
	}
}

3.链式栈的常用操作

①链栈的初始化

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_10
void initstack(linkstack& s)
{
	s = NULL;   //链式栈的初始化
}

②判断链栈是否为空

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_C++_11
bool emptystack(linkstack& s)
{
	if (s == NULL)    //初始化下的状态就是一个空栈
		return true;
	else
		return false;
}

③链栈的入栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_数据结构_12
int push(linkstack& s,selemtype e)
{
	linkstack p;
	p = new stacknode;   //创建在链式栈中的新结点
	p->data = e;  //将要入栈的数据元素赋给结点的数据域
	p->next = s;  //链式栈中指针域是向前指的,所以将新结点的指针域指它前面s指针所指向的位置
	s = p;    //再将指针s后移,进行下次的操作
	return 1;
}

④链栈的出栈

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_堆栈_13
int pop(linkstack& s, selemtype e)
{
	if (s == NULL) {
		return 0;
	}
	else {
		linkstack p;
		e=s->data;
		p = s;   
		s = s->next;
		delete p;
		return 1;
	}
}

⑤取栈顶元素

【奇妙的数据结构世界】用图像和代码对堆栈的使用进行透彻学习 | C++_C++_14
selemtype gettop(linkstack &s)
{
	if (s != NULL)   //栈顶指针存在
		return s->data;   //取出此刻栈顶的数据元素
}

以上就是我们这节对堆栈的全部学习,堆栈的基本运算我在上面基本都已经讲到,希望可以对你有所帮助。我认为图形与代码的结合是学习数据结构算法的核心关键。用图来理解代码,用代码来实现图形。这样不光可以很好的提高我们的代码编程能力,还可以提高我们的抽象逻辑思维能力。

<您的三连和关注是我最大的动力>
🚀 文章作者:Keanu Zhang 分类专栏:算法之美(C++系列文章)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK