数据结构——线性表之 栈 和 队列,详细解析

可以先了解线性表的无头单向非循环链表(单链表)---数据结构——单链表的增加、删除、查找、修改,详细解析_昵称就是昵称吧的博客-优快云博客,和线性表的带头双向循环链表---数据结构:带头双向循环链表——增加、删除、查找、修改,详细解析_昵称就是昵称吧的博客-优快云博客


目录

一、线性表之栈

1、栈的表示和实现

1.1栈的概念及结构

1.2栈的实现表示方法

2、设计栈的功能实现

2.1栈空间通过动态存储数据

2.2栈空间的初始化

2.3栈空间的销毁

2.4入栈的功能

2.5打印栈里数据的功能

2.6出栈的功能

2.7返回栈顶的数据

2.8返回栈里的数据的个数

2.9判断栈里是否有数据

3、总代码

4、 代码运行实例

二、线性表之队列

1、栈的表示和实现 

1.1队列的概念和结构

 1.2队列的实现表示方法

2、设计队列的功能实现

2.1单链表节点的设计

2.2队列的特殊处理

2.3初始化指针head和指针tail

2.4队尾入(尾插) 

2.5对头出(头删)

2.6返回对头的数据(链表里的第一个节点的数据)

2.7返回队尾的数据(链表里的尾节点的数据)

2.8返回队列(链表)里的数据个数

2.9判断链表里是否有元素

2.10队列空间的销毁

3、总代码

4、代码运行实例


一、线性表之栈

1、栈的表示和实现

1.1栈的概念及结构

:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除。
操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。

压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈,出数据也在栈顶。

可以将栈理解为弹夹,压栈就是压入子弹,出栈就是打出子弹。

结构如下所示: 


1.2栈的实现表示方法

栈的实现一般可以使用数组或者链表实现,相对而言数组的结构实现更优一些。因为数组在尾上插入数据的代价比较小。


2、设计栈的功能实现

2.1栈空间通过动态存储数据

typedef int StackDataType;//重定义类型名

typedef struct Stack
{
	StackDataType* a;//创建一个指针,用来接收数组首元素地址,数组里面的类型是StackDataType
	                 //用数组来描述栈,因为出栈和入栈都是一个地方
	int top;//相当于数组的下标,可以是0或-1,这里我们选择0
	int capacity;//数组的容量
}ST;

结构体里用一个指针接收动态开辟的内存空间的地址。 


2.2栈空间的初始化

//初始化结构体,将结构体变量的地址传递过来,是地址传递,这样就能改变实参的内容了
void StackInit(ST* ps)
{
	assert(ps);//地址传递,断言好习惯

	//动态开辟一个数组的空间,数组的元素类型是StackDataType,将首元素地址赋给指针a
	ps->a = (StackDataType*)malloc(sizeof(StackDataType) * 4);
	if (ps->a == NULL)//判断是否成功开辟动态空间
	{
		perror("the mistake is");
	}

	ps->top = 0;        //相当于数组下标,可以初始化0或-1,这里用0
	                    //用0数组下标从0开始,用-1数组下标从-1开始

	ps->capacity = 4;   //从开辟的动态空间可以看出数组的容量是4
}

通过地址传递,初始化结构体里的内容。 


2.3栈空间的销毁

//销毁结构体里的内容,地址传递,才能改变实参的内容
void StackDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);//释放动态开辟的内存
	ps->a = NULL;

	ps->top = 0; //将结构体里的 相当于数组下标top 和 容量capacity 置为0
	ps->capacity = 0;
}

通过释放函数free释放动态开辟的内存,达到销毁栈空间的目的。 


2.4入栈的功能

//入栈,相当于往数组填充数据x
void StackPush(ST* ps,StackDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)//申请的动态空间满了,数组的元素和容量相等,需要增容
	{
		//用relloc函数申请动态空间,创建临时指针变量是怕动态开辟空间失败,增容一般是上一次的2倍
		//注意realloc和malloc函数里的参数,realloc有两个,malloc只有一个
		StackDataType* tmp = (StackDataType*)realloc(ps->a, sizeof(StackDataType) * ps->capacity * 2);

		if (tmp == NULL)//判断是否成功开辟动态空间
		{
			perror("the mistake is");
		}
		else  //增容成功
		{
			//printf("增容成功\n");
			ps->a = tmp;//将新开辟的动态空间地址赋给指针a
			ps->capacity *= 2;
		}
	}

	//不需要增容或增容之后
		ps->a[ps->top] = x;//想数组填充数据
		ps->top++;  /
### 回答1: 线性表都是数据结构中的基本概念,它们之间有一些区别联系。 区别: 1. 存储方式不同:线性表的存储方式是连续的,而的存储方式是离散的。 2. 访问方式不同:线性表可以随机访问元素,而只能访问顶元素。 3. 插入删除操作不同:线性表的插入删除操作可以在任何位置进行,而只能在顶进行。 联系: 1. 可以使用线性表来实现。 2. 线性表都具有顺序存储链式存储两种存储方式。 3. 线性表都可以用于解决许多实际问题,例如表达式求值、逆波兰表达式、括号匹配等问题。 ### 回答2: 线性表数据结构中常见的两种数据组织方式,它们既有区别也有联系。 首先,线性表数据结构上有着不同的实现方式。是一种特殊的线性表,它的特点是先进后出(LIFO)的数据结构,只能在顶进行插入删除操作,没有随机访问的能力。而线性表是一种具有顺序存储结构或链式存储结构的数据结构,它的元素之间存在一对一的关系。 其次,线性表在应用场景上也有所区别。由于具有后进先出的特点,常用于解决一些需要记忆、回溯或递归的问题,如函数调用过程、表达式求值、括号匹配等。而线性表则适用于需要随机访问、插入删除的场景,如数组、链表等。 另外,线性表之间也有一些联系。首先,可以使用线性表的顺序存储结构链式存储结构来实现。其次,可以通过入操作,模拟线性表的插入删除操作。最后,线性表在实际应用中常常配合使用,例如使用来实现逆波兰表达式的计算过程。 总结起来,线性表数据结构上的实现方式操作规则上有所区别,是一种特殊的线性表,它们在应用场景上也有所不同。然而,它们也存在联系,可以使用线性表的实现方式来实现,且可以模拟线性表的插入删除操作。 ### 回答3: 线性表是两种常见的数据结构,有一些区别联系,具体如下: 1. 区别: - 结构不同:是一种后进先出(LIFO)的数据结构,只能在顶进行插入删除操作;而线性表是一种有序的数据结构,可以在任意位置进行插入删除操作。 - 元素访问:只能访问顶的元素,而线性表可以通过索引访问任意位置的元素。 - 功能不同:主要用于实现操作的撤销、函数调用算法中的临时存储,而线性表可以用于存储访问一组有序的数据。 2. 联系: - 数据结构线性表都是基本的数据结构,是其他高级数据结构的基础。 - 共同操作:线性表都支持插入、删除访问元素的操作,而且都可以用数组链表两种方式来实现。 总之,线性表是两种不同的数据结构具有后进先出的特点,只能在顶进行操作,而线性表则没有限制,可以在任意位置进行操作。尽管两者有一些不同之处,但它们都是基本的数据结构,可以在不同的场景中使用。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值