【2022/3/26】栈和队列

1.栈和队列基本概念

在数组中,我们可以通过索引(下标)随机访问元素。但是,在某些情况下,外面可能需要限制处理顺序,这就产生了栈和队列这两种功能受限的线性结构。

栈(stack)

先进后出:LIFO(last in first out)
在这里插入图片描述

栈只有一个开口,先进去的就到下面,后进来的就在上面(top),要是拿出去的话,肯定是先从开口段拿出去,所以说

队列(queue)

在这里插入图片描述

先进先出:FIFO(first in first out)

队列中有队首(front)和队尾(back),队首指向队列的第一个数据,队尾指向队列的最后一个数据。数据从队尾入队,从队首出对。

2.栈和队列的功能实现

1.栈的基本操作:增、删、查、改。

在这里插入图片描述

栈的结构可以用数组或者链表实现。

1.栈结构的声明

typedef int Type;

#define STACK_SIZE 10//栈的最大大小
/*顺序栈结构的声名*/

typedef struct Stack
{
	Type data[STACK_SIZE];//栈的数据域
	int top;//栈顶元素下标
}stack;

2.栈的初始化

使用malloc动态开辟一个stack大小的内存

初始化栈顶的元素下标

stack* stack_init()
{
	stack* temp = (stack*)malloc(sizeof(stack));
	/*if (NULL == temp)
	{
		printf("初始化栈失败!\n");
		return NULL;
	}*/
	assert(temp);//断言(报错)函数(来自断言头文件):
	//当函数参数为NULL或者0时会断言(中断程序执行并弹出报错窗口)

	
	temp->top = -1;//初始化栈顶元素下标top值为-1(-1表示栈中没有数据,栈为空)
	
}

3.栈的创建

见上

4.数据入栈

void stack_push(stack* st, Type val)
{
	assert(st);//判断栈是否存在
	assert(!stack_full(st));//判断栈是否满
	st->data[++st->top] = val;//向栈顶插入数据
}

5.数据出栈

数据出栈需要取出栈顶的元素,所以要将元素下标top作自减

Type stack_pop(stack* st)
{
	assert(st);//判断栈是否存在
	assert(!stack_empty(st));//判断是否空
	return st->data[st->top--];//返回栈顶元素
}

6.获取栈顶元素

获取元素但不出栈,和数据出栈的差距是不需要作自减操作

Type stack_top(stack* st)
{
	assert(st);//判断栈是否存在

	return st->data[st->top];//返回栈顶元素
}

7.判断栈空

int stack_full(stack* st)
{
	//if (st->top >= STACK_SIZE - 1);
	//return 1;//栈满
	//return 0;//栈没满
	return st->top >= STACK_SIZE - 1;
}

8.判断栈满

int stack_empty(stack* st)
{
	return st->top==-1;//如果栈为空则返回非0值(返回1),否则返回0
}

2.队列的基本操作:增删查改

1.队列结构体的声明

typedef int Type;
typedef struct node {//链队节点结构体的声明
	Type data;//数据域
	struct node* next;//指针域
}Node;
typedef struct queue {//整个链队的结构声明
	Node* front;//队首指针
	Node* front;//队尾指针
}Queue;
//队列的功能声明

2.队列的初始化

Queue* queue_init()
{
	Queue* temp = (Queue*)malloc(sizeof(Queue));

	assert(temp);
	temp->front = temp->back = NULL;//队首和队尾创建并初始化为空
	return temp;
}

3.队列的创建

Node* node_create(Type val)
{
	Node* temp = (Node*)malloc(sizeof(Node));

	assert(temp);
	temp->data = val;
	temp->next = NULL;
	return temp;
}

4.数据入队

void queue_push(Queue* q, Type val)
{
	assert(q);

	if (NULL == q->front)
	{
		//队列中只有一个节点,此节点既是队首也是队尾
		q->front = q->back = node_create(val);
	}
	else
	{
		q->back = q->back->next = node_create(val);
		//创建新节点并连接上链表尾部,新节点成为新的尾部
	}
}

5.数据出队

Type queue_pop(Queue* q)
{
	assert(q);
	assert(q->front);

	Node* temp = q->front;//记录被删除节点的位置
	Type val = temp->data;//记录被删除节点的数据

	q->front = q->front->next;//队首节点的下一个节点成为新的队首
	free(temp);//释放原来的队列
	temp = NULL;//防止野指针
	return val;
}

6.获取队首元素

Type queue_front(Queue* q)
{
	assert(q);//判断整个链表是否存在
	assert(q->front);//判断链表是否为空
	return q->front->data;//返回队首元素
}

7.获取队尾元素

Type queue_back(Queue* q)
{
	assert(q);//判断整个链表是否存在
	assert(q->back);//判断链表是否为空
	return q->back->data;//返回队尾元素
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值