栈和队列的基本实现

一、栈

1、定义

1、栈(Stack)是限定仅在表尾(栈顶)进行插入和删除的线性表,特点:后进先出

2、栈有顺序存储结构也有链式存储结构;

顺序存储结构:利用一组地址连续的存储单元依次存放栈底到栈顶的数据元素,可用top=0/-1表示栈内元素个数情况,下面将展示top=0表示栈为空进行的一系列初始操作

栈的顺序存储表示
typedef int STDataType;
//栈的实现可以用顺序栈(数组)也可以用链栈(栈顶为首元结点),数组较为方便
// 以下为顺序栈的实现
//typedef struct Stack//静态(大小固定)
//{
//	STDataType a[N];
//	int size;
//};
typedef struct
{
	STDataType* a;//栈元素的首地址
	int top;//栈顶指针
	int capacity;//栈所占空间
}Stack;
栈的基本操作函数
头文件(文件名Stack.h)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include<stdlib.h>
#define N 100
#define Increment 10//每次扩容时的增量
typedef int STDataType;//将int换个名字

//接口函数的声明
void InitStack(Stack* pst);//初始化栈
void DestoryStack(Stack* pst);//销毁栈
void StackPush(Stack* pst,STDataType x);//入栈
STDataType StackPop(Stack* pst);//出栈
int  StackSize(Stack* pst);//获取栈元素的个数
int  StackEmpty(Stack* pst);//判断栈是否为空
STDataType GetTop(Stack* pst);//获取栈顶的数据
接口函数的实现
#include "Stack.h"
void InitStack(Stack* pst)//初始化栈
{
	assert(pst);//断言,防止不慎传入的结构体指针为空
	pst->a = (STDataType*)malloc(sizeof(STDataType) * 100);//先给栈分配一个空间,首地址为pst->a
	pst->top = 0;
	pst->capacity = 100;
}
void DestoryStack(Stack* pst)//销毁栈
{
	assert(pst);
	free(pst->a);
	pst->a = NULL;
	pst->top = 0;
	pst->capacity = 0;
}
void StackPush(Stack* pst,STDataType x)//入栈
{//Increment扩容增量
	assert(pst);
	if (pst->capacity == pst->top)//空间满了扩容
	{
		pst->a = (STDataType*)realloc(pst->a, (pst->capacity + Increment) * sizeof(STDataType));
		if (!pst->a)exit(-1);
		pst->capacity = pst->capacity + Increment;
	}
	pst->a[pst->top] = x;
	pst->top++; 
}
STDataType StackPop(Stack* pst)//出栈
{//返回出栈的栈顶元素
	assert(pst);
	assert(pst->top > 0);
	return pst->a[--pst->top];
//	pst->top--;
}
int  StackSize(Stack* pst)//获取栈元素的个数
{
	assert(pst);
	return pst->top;
}
int  StackEmpty(Stack* pst)//判断栈是否为空
{
	assert(pst);
	if (pst->top == 0)return 1;
	else return 0;
}
STDataType GetTop(Stack* pst)//获取栈顶的数据
{
	assert(pst);
	assert(pst->top > 0);
	return pst->a[pst->top - 1];
3.实践部分与运行截图
#define _CRT_SECURE_NO_WARNINGS
#include "Stack.h"
void TestStack1()
{
	Stack s1;
	InitStack(&s1);//初始化
	StackPush(&s1, 1);//入栈四个元素1234
	StackPush(&s1, 2);
	StackPush(&s1, 3);
	StackPush(&s1, 4);
	while (!StackEmpty(&s1))//从栈顶4开始逐个打印
	{
		printf("%d ", GetTop(&s1));//获取栈顶元素
		StackPop(&s1);//出栈一个
	}
	printf("\n");
	StackPush(&s1, 5);
	int x=0;
	x=StackPop(&s1);//将出栈的栈顶元素赋值给x
	printf("%d\n", x);
}
int main()
{
	TestStack1();
	return 0;
}

栈的链式存储表示

根据栈后进先出的特点,因此进行操作时采用头插和头删,和单链表相似。

二、队列

1、定义

只允许在表的一端插入和另一端删除,特点:先进先出,类似于排队打饭,先排队的先打饭。

2、队列的链式存储结构

1、头文件
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QNode* next;
}QueueNode;
typedef struct Queue
{
	QueueNode* head;//头指针用来指向队头
	QueueNode* tail;//尾指针用来指向队尾
}Queue;
void QueueInit(Queue* pq);//初始化队列
void QueueDestory(Queue* pq);//销毁队列
void QueuePush(Queue* pq,QDataType x);//进队列
void QueuePop(Queue* pq);//出队列
QDataType QueueFront(Queue* pq);//取队头数据
QDataType QueueBack(Queue* pq);//取队尾数据
int QueueEmpty(Queue* pq);//判断队列是否为空
int QueueSize(Queue* pq);//求队列元素个数
2、基本函数实现
#include "Queue.h"
void QueueInit(Queue* pq)//初始化队列
{//pq为结构体指针,是结构体的地址,队头队尾指针存放在结构体中因此不用传二级指针
	pq->head = NULL;
	pq->tail = NULL;
}
void QueueDestory(Queue* pq)//销毁队列
{
	QueueNode* cur = pq->head;
	while (cur)
	{
		QueueNode* next = cur->next;//next保存队列的下一个元素
		free(cur);//将队头删掉
		cur = next;
	}
	pq->head = NULL;
	pq->tail = NULL;
}
void QueuePush(Queue* pq, QDataType x)//进队列
{
	assert(pq);
	QueueNode* newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		printf("内存不足\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->head == NULL)//当队列为空时
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;//新尾插结点
	}
}
void QueuePop(Queue* pq)//出队列
{//先保存下一个再头删
	assert(pq);
	assert(pq->head != NULL);
	if (pq->head->next == NULL)//当队列只剩一个元素时
	{
		free(pq->head);
		pq->head = NULL;
		//pq->tail=NULL;
	}
	else
	{
		QueueNode* cur = pq->head->next;//用cur保存队头的下一个元素
		free(pq->head);
		pq->head = cur;
	}
}
QDataType QueueFront(Queue* pq)//取队头数据
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}
QDataType QueueBack(Queue* pq)//取队尾数据
{
	assert(pq);
	assert(pq->tail);
	return pq->tail->data;
}
int QueueEmpty(Queue* pq)//判断队列是否为空
{
	assert(pq);
	return pq->head == NULL ? 1 : 0;
}
int QueueSize(Queue* pq)//求队列元素个数
{
	int size = 0;
	assert(pq);
	QueueNode* cur = pq->head;
	while (cur)
	{
		cur = cur->next;
		size++;
	}
	return size;
}
3、实践部分和运行截图
#include "Queue.h"
void TestQueue1()
{
	Queue q;//队列结构体指针
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePush(&q, 3);
	QueuePush(&q, 4);
	
	while (!QueueEmpty(&q))
	{
		//printf("%d ",q.head->data);
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}
	printf("\n");
	QueueDestory(&q);//销毁队列
	QueuePush(&q, 5);//销毁之后插入5然后取队头
	printf("%d ", QueueFront(&q));
}
int main()
{
	TestQueue1();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值