栈与队列知识点总结

一.栈

:⼀种特殊的线性表,其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作 的⼀端称为栈顶,另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。栈和顺序表具有很高的相似性,因此这里不进行详细的讲解。

入栈出栈的示意图

补充

栈和顺序表虽然很相似但是栈的出栈不能通过遍历,因为栈的出栈是从栈顶到栈底的,需要依次出栈顶元素

while (!StEmpty(&st))
{
	typedate data = StTop(&st);
	printf("%d ", data);
	StPop(&st);
}

二.队列

队列:只允许在⼀端进⾏插⼊数据操作,在另⼀端进⾏删除数据操作的特殊线性表,队列具有先进先 出FIFO(First Inc First Out)。

队列解析示意图

 数组与链表在队列中的优越性:使⽤链表的结构实现更优⼀些,因为如果使⽤数组的结构,出队 列在数组头上出数据,效率会⽐较低。

三.后附代码

stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int typedate;
typedef struct stack
{
	typedate * arr;
	int capacity;
	int top;//相当于顺序的size
}ST;
//初始化
void StInit(ST*st);
// 插入
void StPush(ST* st,typedate x);
//判断是否为空
bool StEmpty(ST* st);
// 出栈
void StPop(ST* st);
//取栈顶元素
typedate StTop(ST* st);
//销毁
void StDestory(ST* st);
stack.c
#include"Stack.h"
void StInit(ST* st)
{
	assert(st);
	st->arr = NULL;
	st->capacity = st->top = 0;
}
// 插入
void StPush(ST* st, typedate x)
{
	assert(st);
	//判断空间是否满足
	if (st->capacity == st->top)
	{
		int newcapacity = st->capacity == 0 ? 4 : 2 * st->capacity;
		typedate*temp = (typedate*)realloc(st->arr,sizeof(typedate)*newcapacity);
		if (temp == NULL)
		{
			perror("fail!!!");
			exit(1);
		}
		st->arr = temp;
		st->capacity = newcapacity;
	}
	st->arr[st->top++] = x;
}
//判断是否为空
bool StEmpty(ST* st)
{
	assert(st);
	return st->top == 0;
}
// 出栈
void StPop(ST* st)
{
	assert(st);
	assert(!StEmpty(st));
	--st->top;
}
//取栈顶元素
typedate StTop(ST* st)
{
	assert(st);
	assert(!StEmpty(st));
	return st->arr[st->top - 1];
}
//销毁
void StDestory(ST* st)
{
	assert(st);
	if (st->arr)
	{
		free(st->arr);
	}
	st->arr = NULL;
	st->capacity = st->top = 0; 
}
test.c
#include"Stack.h"
void test()
{
	ST st;
	StInit(&st);
	//初始化
	StInit(&st);
	// 插入
	StPush(&st, 1);
	StPush(&st, 2);
	StPush(&st, 3);
	StPush(&st, 4);
	StPush(&st, 5);
	//打印
	while (!StEmpty(&st))
	{
		typedate data = StTop(&st);
		printf("%d ", data);
		StPop(&st);
	}
	//销毁
	StDestory(&st);
}
int main()
{
	test();
	return 0;
}

队列

Queue.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
//指向节点的
typedef int typedate;
typedef struct QueueNode
{
	typedate date;
	struct QueueNode* next;

}QNode;
//指向队列的两个指针
typedef struct Queue
{
	QNode* pphead;
	QNode* tail;
	int size;
}Qu;
//队列初始化
void QueueInit(Qu* pq);
//销毁队列
void QueueDestory(Qu* pq);
//判断是否为空
bool QueueEmpty(Qu* pq);
//入队列
void QueuePush(Qu* pq, typedate x);
//出队
void  QueuePop(Qu* pq);
//取队顶元素
typedate QueueTop(Qu* pq);
//取队尾数据
typedate QueueBack(Qu* pq);
//队列有效元素个数
int QueueSize(Qu* pq);
//销毁队列
void QueueDestroy(Qu* pq);
Queue.c
#include"Queue.h"
//队列初始化
void QueueInit(Qu* pq)
{
	assert(pq);
	pq->pphead = pq->tail = NULL;
	pq->size = 0;
}
//入队列
void QueuePush(Qu* pq, typedate x)
{
	assert(pq);
	//申请节点
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail!!!");
		exit(1);
	}
	newnode->date = x;
	newnode->next = NULL;
	//第一种情况没有元素的情况
	if (pq->pphead == NULL)
	{
		pq->pphead = pq->tail = newnode;
	}
	else
	{
		pq->tail->next=newnode;
		pq->tail = pq->tail->next;
	}
}
//判断是否为空
bool QueueEmpty(Qu* pq)
{
	assert(pq);
	return pq->pphead ==NULL && pq->tail == NULL;
}
//出队
void  QueuePop(Qu* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	//两种情况
	if (pq->pphead == pq->tail)
	{
		free(pq->pphead);
		pq->pphead = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->pphead->next;
		free(pq->pphead);
		pq->pphead = next;
	}
	--pq->size;
}
//取队顶元素
typedate QueueTop(Qu* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->pphead->date;
}
//取队尾数据
typedate QueueBack(Qu* pq) 
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->date;
}
//队列有效元素个数
int QueueSize(Qu* pq)
{
	assert(pq);
	return pq->size;
}
//销毁队列
void QueueDestroy(Qu* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	QNode* pcur = pq->pphead;
	while (pcur)
	{
		QNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->pphead = pq->tail = NULL;
	pq->size = 0;

}
test.c
#include"Queue.h"
void Queuetest()
{
	Qu q;
	//队列初始化
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);

	QueuePop(&q);

	printf("head:%d\n", QueueTop(&q));
	printf("tail:%d\n", QueueBack(&q));
	printf("size:%d\n", QueueSize(&q));
	QueueDestroy(&q);
}
int main()
{
	Queuetest();
	return 0;
}

总结

适用于后进先出方式处理数据,并且允许在任何时候只能访问或修改位于其顶端项队列适用于先进先出方式处理数据,并且允许在任何时候只能访问或修改排在其前端各项。虽然它们有不同之处,但都是非常重要且应用广泛。最后期待各位大佬的指正,留下一键三连(点赞,收藏,关注)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值