栈和队列--C语言

欢迎来到本期频道!- - -

本期介绍《栈和队列》

定义

栈的概念

栈:一种特殊的线性表,其只能在特定的一端插入/删除数据.
疑问:为啥是特殊的线性表?- - -只能在一端进出数据,既后进先出.
栈顶:插入/删除数据的一端.
栈底:与栈顶相反的另一端.
压栈:在栈顶插入数据.
出栈:在栈顶删除数据.

队列的概念

队列:一种特殊线性表,其只能在一端插入数据,另一端删除数据.
疑问:这个又特殊在哪?- - -只能一端进数据,另一端出数据,既先进先出.
队头:删除数据的一端.
队尾:插入数据的一端,既与对头相反的另一端.
入队:从队尾插入数据.
出队:从队头删除数据.

结构

栈的结构

入栈

请添加图片描述

出栈

请添加图片描述

由以上可以明白栈的结构是符合 后进先出原则的.

队列的结构

入队

请添加图片描述

出队

请添加图片描述

由以上可以明白队列的结构是符合 先进先出原则的.

实现

栈的实现

实现栈,可以用顺序表或者链表.
因为在尾插方面,顺序表消耗较小,我们选择顺序表实现栈.

Stack.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<vld.h>
#include<assert.h>
#include<stdbool.h>

//栈是一种特殊的线性表

typedef int STdatatype;
typedef struct Stack
{
	STdatatype* p;		//用于存放栈中的数据
	int top;	    	//维护栈顶	
	int capacity;	 	//记录当前申请的空间大小
}ST;

#define INIT_CAPACITY	4
//栈的初始化和销毁
void STinit(ST* st);
void STdestroy(ST* st);

//入栈和出栈
void STpush(ST* st,STdatatype x);
void STpop(ST* st);

//读取栈顶数据
STdatatype STgettop(ST* st);
//检查容量
void STcheck_room(ST* st);
//判断是否为空
bool STempty(ST* st);

//有效数据数量
int STdata_quantity(ST* st);

Stack.c

#include"Stack.h"
//栈的初始化和销毁
void STinit(ST* st)
{
	assert(st);
	st->p = NULL;
	st->top = st->capacity = 0;		//top指向栈顶数据的上一个位置
}
void STdestroy(ST* st)
{
	assert(st);
	free(st->p);
	st->top = st->capacity = 0;
}

//入栈和出栈
void STpush(ST* st,STdatatype x)
{
	assert(st);
	STcheck_room(st);
	st->p[st->top++] = x;
}
void STpop(ST* st)
{
	assert(st);
	assert(st->top);
	st->top--;
}


//读取栈顶数据
STdatatype STgettop(ST* st)
{
	assert(st);
	assert(st->top);
	return st->p[st->top - 1];
}
//检查容量
void STcheck_room(ST* st)
{
	assert(st);
	if (st->top == st->capacity)
	{
		int newcapacity = (st->capacity == 0) ? INIT_CAPACITY : (st->capacity * 2);
		STdatatype* temp = (STdatatype*)realloc(st->p, sizeof(STdatatype) * newcapacity);
		if (temp == NULL)
		{
			perror("STcheck_room malloc fail");
			exit(1);
		}
		st->p = temp;
		st->capacity = newcapacity;
	}
}
//判断是否为空
bool STempty(ST* st)
{
	assert(st);
	return !st->top;
}

//有效数据数量
int STdata_quantity(ST* st)
{
	assert(st);
	return st->top;
}

队列的实现

实现队列,同样可以使用顺序表或者链表.
由于顺序表在数组头部出数据时,效率较低,故我们选择链表实现队列.

Queue.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"vld.h"
#include<stdlib.h>

typedef int QDataType;
// 链式结构:表示队列 
typedef struct QListNode
{
	struct QListNode* next;
	QDataType data;			//队列中的数据
}QNode;

//对头和队尾
typedef struct Queue	//便于维护
{
	QNode*  head;
	QNode*	tail;
	int size;		//便于计算有效数据个数
}Queue;

// 初始化队列 
void QueueInit(Queue* q);
// 销毁队列 
void QueueDestroy(Queue* q);


// 队尾入队列 
void QueuePush(Queue* q, QDataType data);
// 队头出队列 
void QueuePop(Queue* q);


// 获取队列头部元素 
QDataType QueueFront(Queue* q);
// 获取队列队尾元素 
QDataType QueueBack(Queue* q);


// 获取队列中有效元素个数 
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q);

Queue.c

#include"Queue.h"
// 初始化队列 
void QueueInit(Queue* q)
{
	assert(q);
	q->head = NULL;
	q->tail = NULL;
	q->size = 0;
}

// 销毁队列 
void QueueDestroy(Queue* q)
{
	assert(q);
	QNode* cur = q->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	q->head = q->tail = NULL;
	q->size = 0;
}

// 队尾入队列 
void QueuePush(Queue* q, QDataType data)
{
	assert(q);
	QNode* new = (QNode*)malloc(sizeof(QNode));
	if (new == NULL)				
	{
		perror("QuePush malloc fail");
		exit(1);
	}
	new->data = data;
	new->next = NULL;

	if (q->tail == NULL)	//如果队列为空
	{
		q->head=q->tail = new;
	}
	else			//队列不为空 尾插
	{
		q->tail->next = new;
		q->tail = new;
	}

	q->size++;

}

// 队头出队列 
void QueuePop(Queue* q)
{
	assert(q);
	assert(q->size);

	QNode* next = q->head->next;
	free(q->head);
	q->head = next;
	q->size--;

	if (q->size == 0)		//出完了,要置空
	{
		q->head = q->tail = NULL;
	}
}

// 获取队列头部元素 
QDataType QueueFront(Queue* q)
{
	assert(q);
	assert(q->size);
	return q->head->data;
}

// 获取队列队尾元素 
QDataType QueueBack(Queue* q)
{
	assert(q);
	assert(q->size);
	return q->tail->data;
}

// 获取队列中有效元素个数 
int QueueSize(Queue* q)
{
	assert(q);
	return q->size;
}

// 检测队列是否为空,如果为空返回非零结果,如果非空返回0 
int QueueEmpty(Queue* q)
{
	assert(q);
	return q->size == 0;
}

总结:

在这里插入图片描述

本期分享就到这里了,希望能让你更热爱C语言。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值