数据结构:3.栈和队列

1.概念

1).栈

  • 栈是一种先进后出、后进先出的数据结构
  • 队列时钟先进先出、后进后出的数据结构
  • 栈、队列、表的区别
    • 栈和队列是一种特殊的表状结构
    • 栈和队列只能在特定的位置插入和删除
    • 表可以在任意位置插入和删除
    • 栈顶:允许入栈和出栈的一端
    • 栈底:不允许入栈和出栈的一端
    • 栈针:指向栈顶位置的指针或下表
  • 栈的分类
    • 增栈:栈向高地址增长
    • 减栈:栈向低地址增长
    • 空栈:指针指向入栈位置
    • 满栈:指针指向栈顶位置
    • 分类:空增栈、满增栈、空减栈、满减栈
  • 入栈(压栈):将数据插入栈顶元素的位置
  • 出栈(弹栈):将数据从栈顶元素位置取出

2).队列

  • 队头:出队的一端
  • 队尾:入队的一端
  • 出队:数据从队列中取出
  • 入队:数据向队列中插入

2.顺序栈

下为顺序栈的创建,入栈,出栈,判断空栈和满栈,销毁栈,seqstack.c文件

cs 复制代码
#include"seqstack.h"

SeqStack_t *CreateSeqStack(int MaxLen)
{
	SeqStack_t *pTmpStack = NULL;

	pTmpStack = malloc(sizeof(SeqStack_t));
	if (NULL == pTmpStack)
	{
		perror("fail to malloc");
		return NULL;
	}
	
	pTmpStack->pData = malloc(MaxLen * sizeof(DataType));
	if (NULL == pTmpStack->pData)
	{
		perror("fail to malloc");
		return NULL;
	}

	pTmpStack->top = 0;
	pTmpStack->maxlen = MaxLen;

	return pTmpStack;
}

int DestroySeqStack(SeqStack_t **ppStack)
{
	free((*ppStack)->pData);
	free(*ppStack);
	*ppStack = NULL;

	return 0;
}

int IsEmptySeqStack(SeqStack_t *pStack)
{
	return pStack->top == 0 ? 1 : 0;
}

int IsFullSeqStack(SeqStack_t *pStack)
{
	return pStack->top == pStack->maxlen ? 1 : 0;
}

int PushSeqStack(SeqStack_t *pStack, DataType TmpData)
{
	if (IsFullSeqStack(pStack))
	{
		return -1;
	}

	pStack->pData[pStack->top] = TmpData;
	pStack->top++;

	return 0;
}

DataType PopSeqStack(SeqStack_t *pStack)
{
	if (IsEmptySeqStack(pStack))
	{
		return -1;
	}

	pStack->top--;

	return pStack->pData[pStack->top];
}

main.c

cs 复制代码
#include "seqstack.h"

int main(void)
{
	SeqStack_t *pseqstack = NULL;

	pseqstack = CreateSeqStack(5);
	
	PushSeqStack(pseqstack, 1);
	PushSeqStack(pseqstack, 2);
	PushSeqStack(pseqstack, 3);
	PushSeqStack(pseqstack, 4);
	PushSeqStack(pseqstack, 5);
	PushSeqStack(pseqstack, 6);

	while (!IsEmptySeqStack(pseqstack))	
	{
		printf("%d ", PopSeqStack(pseqstack));
	}
	printf("\n");

	DestroySeqStack(&pseqstack);
	
	return 0;
}

seqstack.h

cs 复制代码
#ifndef __SEQSTACK_H__
#define __SEQSTACK_H__
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
typedef struct seqstack
{
	DataType *pData;
	int top;
	int maxlen;
}SeqStack_t;
//创建顺序栈
extern SeqStack_t *CreateSeqStack(int MaxLen);
//入栈
extern int PushSeqStack(SeqStack_t *pStack, DataType TmpData);
//判断是否满栈
extern int IsFullSeqStack(SeqStack_t *pStack);
//判断是否空栈
extern int IsEmptySeqStack(SeqStack_t *pStack);
//出栈
extern DataType PopSeqStack(SeqStack_t *pStack);
//销毁栈
extern int DestroySeqStack(SeqStack_t **ppStack);

#endif

3.循环队列

下为链式栈的创建,入栈,出栈,判断空栈,销毁栈,linkseqstack.c文件

cs 复制代码
#include"linkstack.h"
Node_t *CreateEmptyLinkStack(void)
{
	Node_t *pTmpStack = NULL;
	pTmpStack = malloc(sizeof(Node_t));
	if(pTmpStack == NULL)
	{
		perror("fail to malloc");
		return NULL;
	}
	pTmpStack->pnext = NULL;
	return pTmpStack;
}
int IsEmptyLinkStack(Node_t *pHead)
{
	return pHead->pnext == NULL?1:0;
}
int PushLinkStack(Node_t *pHead,DataType TmpData)
{
	Node_t *pTmpStack = malloc(sizeof(Node_t));
	if(pTmpStack == NULL)
	{
		perror("fail to malloc");
		return -1;
	}
	pTmpStack->Data = TmpData;
	pTmpStack->pnext = pHead->pnext;
	pHead->pnext = pTmpStack;
	return 0;
}
DataType popLinkStack(Node_t *pHead)
{
	Node_t *pFreeStack = pHead->pnext;
	DataType a = 0;
	if(IsEmptyLinkStack(pHead))
		return -1;
	pHead->pnext = pFreeStack->pnext;
	a = pFreeStack->Data;
	free(pFreeStack);
	pFreeStack = NULL;
	return a;
}
int DestroyLinkStack(Node_t **ppHead)
{
	Node_t *pTmpStack = NULL;
	Node_t *pFreeStack = NULL;
	pTmpStack = pFreeStack = *ppHead;
	while(pTmpStack != NULL)
	{
		pFreeStack = pTmpStack;
		pTmpStack = pTmpStack->pnext;
		free(pFreeStack);
	}
	*ppHead = NULL;
}

main.c

cs 复制代码
#include"linkstack.h"
int main(void)
{
	Node_t *year = CreateEmptyLinkStack();
	PushLinkStack(year,1);
	PushLinkStack(year,3);
	PushLinkStack(year,5);
	PushLinkStack(year,7);
	PushLinkStack(year,9);
	//while(year->top != 0)
	while(!IsEmptyLinkStack(year))
		printf("%d ",popLinkStack(year));
	putchar('\n');
	printf("未销毁:%p\n",year);
	DestroyLinkStack(&year);
	printf("已销毁:%p\n",year);
	return 0;
}

linkstack.h

cs 复制代码
#ifndef __LINKSTACK_H__
#define __LINKSTACK_H__

#include<stdio.h>
#include<stdlib.h>

typedef int DataType;
typedef struct linkstack
{
	DataType Data;
	struct linkstack *pnext;
}Node_t;

Node_t *CreateEmptyLinkStack(void);
int IsEmptyLinkStack(Node_t *pHead);
int PushLinkStack(Node_t *pHead,DataType TmpData);
DataType popLinkStack(Node_t *pHead);
int DestroyLinkStack(Node_t **ppHead);

#endif

4.循环队列

下为循环队列的创建,入队,出队,判断空和满,销毁,seqqueue.c文件

cs 复制代码
#include"seqqueue.h"
SeqQueue_t *CreateSeqQueue(int len)
{
	SeqQueue_t *pNowQueue = malloc(sizeof(SeqQueue_t));
	pNowQueue->pData = malloc((len+1)*sizeof(DataType));
	if(pNowQueue == NULL)
	{
		perror("fail to malloc");
		return NULL;
	}
	if(pNowQueue->pData == NULL)
	{
		perror("fail to malloc");
		return NULL;
	}
	pNowQueue->Head = pNowQueue->Tail = 0;
	pNowQueue->MaxLen = len;
	return pNowQueue;
}
int IsFullSeqQueue(SeqQueue_t *pTmpQueue)
{
	return ((pTmpQueue->Tail+1)%(pTmpQueue->MaxLen+1) == pTmpQueue->Head)?1:0;
}
int IsEmptySeqQueue(SeqQueue_t *pTmpQueue)
{
	return (pTmpQueue->Tail == pTmpQueue->Head)?1:0;
}
int EnterSeqQueue(SeqQueue_t *pTmpQueue,DataType TmpData)

{
	if(IsFullSeqQueue(pTmpQueue))
		return -1;
	pTmpQueue->pData[pTmpQueue->Tail] = TmpData;
	TmpData = pTmpQueue->pData[pTmpQueue->Head];
	pTmpQueue->Tail = (pTmpQueue->Tail+1)%(pTmpQueue->MaxLen+1);
	return 0;
}
DataType QuitSeqQueue(SeqQueue_t *pTmpQueue)
{
	DataType TmpData;
	if(IsEmptySeqQueue(pTmpQueue))
		return -1;
	TmpData = pTmpQueue->pData[pTmpQueue->Head];
	pTmpQueue->Head = (pTmpQueue->Head+1)%(pTmpQueue->MaxLen+1);
	return TmpData;
}
int DestroySeqQueue(SeqQueue_t **ppTmpQueue)
{
	free((*ppTmpQueue)->pData);
	free(*ppTmpQueue);
	*ppTmpQueue = NULL;
	return 0;
}

main.c

cs 复制代码
#include"seqqueue.h"
int main(void)
{
	SeqQueue_t *shi = CreateSeqQueue(12);
	int a = 1;
	
	printf("%d \n",IsFullSeqQueue(shi));
	while(!IsFullSeqQueue(shi))
	{
		EnterSeqQueue(shi,a);
		a++;
	}
	putchar('\n');
	while(!IsEmptySeqQueue(shi))
		printf("%d ",QuitSeqQueue(shi));
	putchar('\n');
	printf("%p\n",shi);
	DestroySeqQueue(&shi);
	printf("%p\n",shi);
	return 0;
}

seqqueue.h

cs 复制代码
#ifndef __SEQQUEUE_H__
#define __SEQQUEUE_H__

#include<stdio.h>
#include<stdlib.h>

typedef int DataType;
typedef struct queue
{
	DataType *pData;
	int Head;            //头下标
	int Tail;            //尾下标
	int MaxLen;
}SeqQueue_t;

extern SeqQueue_t *CreateSeqQueue(int len);
extern int IsEmptySeqQueue(SeqQueue_t *pTmpQueue);
extern int IsFullSeqQueue(SeqQueue_t *pTmpQueue);
extern int EnterSeqQueue(SeqQueue_t *pTmpQueue,DataType TmpData);
extern DataType QuitSeqQueue(SeqQueue_t *pTmpQueue);
extern int DestroySeqQueue(SeqQueue_t **ppTmpQueue);

#endif

5.链式队列

下为链式队列的创建,入队,出队,判断是否为空,销毁,linkstack.c文件

cs 复制代码
#include"linkqueue.h"
Node_t *CreateLinkQueue(void)
{
	Node_t *pTmpQueue = malloc(sizeof(Node_t));
	if(pTmpQueue == NULL)
	{
		perror("fail to malloc");
		return NULL;
	}
	pTmpQueue->pNext = NULL;
	return pTmpQueue;
}
int IsEmptyLinkQueue(Node_t *pTmpQueue)
{
	return (pTmpQueue->pNext == NULL)?1:0;
}
int EnterLinkQueue(Node_t *pTmpQueue,DataType TmpData)
{
	Node_t *pNowQueue = malloc(sizeof(Node_t));;
	if(pNowQueue == NULL)
	{
		perror("fail to malloc");
		return -1;
	}
	Node_t *pLastQueue = pTmpQueue;
	while(pLastQueue->pNext != NULL)
	{
		pLastQueue = pLastQueue->pNext;
	}
	pNowQueue->Data = TmpData;
	pNowQueue->pNext = pLastQueue->pNext;//NULL
	pLastQueue->pNext = pNowQueue;
	return 0;
}
DataType QuitlinkQueue(Node_t *pTmpQueue)
{
	DataType TmpData;
	Node_t *pFreeNode = pTmpQueue->pNext;
	if(IsEmptyLinkQueue(pTmpQueue))
		return -1;
	pTmpQueue->pNext = pFreeNode->pNext;
	TmpData = pFreeNode->Data;
	free(pFreeNode);
	pFreeNode = NULL;
	return TmpData;

}
int DestroyLinkQueue(Node_t **ppTmpQueue)
{
	Node_t *pTmpQueue = *ppTmpQueue;
	Node_t *pFreeNode = *ppTmpQueue;
	while(pTmpQueue != NULL)
	{
		pTmpQueue = pFreeNode->pNext;
		free(pFreeNode);
		pFreeNode = pTmpQueue;
	}
	*ppTmpQueue = NULL;
	return 0;
}

main.c

cs 复制代码
#include"linkqueue.h"
int main(void)
{
	Node_t *year = CreateLinkQueue();
	DataType a = 12;
	while(a!=0)
	{
		EnterLinkQueue(year,a);
		a-=2;
	}putchar('\n');
	while(!IsEmptyLinkQueue(year))
	{
		printf("%d ",QuitlinkQueue(year));
	}
	putchar('\n');
	printf("%p\n",year);
	DestroyLinkQueue(&year);
	printf("%p\n",year);
	return 0;
}

linkstack.h

cs 复制代码
#ifndef __LINKQUEUE_H__
#define __LINKQUEUE_H__

#include<stdio.h>
#include<stdlib.h>

typedef int DataType;
typedef struct node
{
	DataType Data;
	struct node *pNext;
}Node_t;
extern Node_t*CreateLinkQueue(void); 
extern int IsEmptyLinkQueue(Node_t *pTmpQueue);
extern int EnterLinkQueue(Node_t *pTmpQueue,DataType TmpData);
extern DataType QuitlinkQueue(Node_t *pTmpQueue);
extern int DestroyLinkQueue(Node_t **ppTmpQueue);


#endif
相关推荐
闪电悠米11 小时前
力扣hot100-41.缺失的第一个正数-原地哈希详解
数据结构·算法·哈希算法
WL学习笔记11 小时前
堆(数据结构)
数据结构·
wabs66615 小时前
关于图论【卡码网100.最大岛屿的面积的思考】
数据结构·算法·图论
yuannl1017 小时前
图的最短路径Dijkstra
数据结构
zander25818 小时前
138. 随机链表的复制
数据结构·算法·链表
过期动态18 小时前
【LeetCode 热题 100】找到字符串中所有字母异位词
java·数据结构·算法·leetcode·职场和发展·rabbitmq
来一碗刘肉面18 小时前
栈在递归中的应用
数据结构·算法
皓月斯语19 小时前
程序设计语言的特点
开发语言·数据结构·c++
邪修king19 小时前
C++ 进阶终章:异常机制与智能指针全解 —— 从错误处理到 RAII 资源管理,打通现代 C++ 的核心命脉
android·数据结构·c++
Adios7941 天前
设置交集大小至少为2
数据结构·算法·leetcode