数据结构-栈和队列

栈和队列

    • 栈的基本概念
    • 栈的结构
    • 初始化栈
    • 销毁栈
    • 压栈
    • 出栈
    • 栈中元素的个数
    • 查找栈顶的元素
    • 压栈和出栈的一个演示
    • 全部代码
      • Stack.h
      • Stack.c
      • Test.c
  • 队列
    • 队列的基本概念
    • 节点和队列的定义
    • 队列的初始化
    • 销毁队列
    • 入队
    • 出队
    • 计算队列中元素的个数
    • 判断队列是否为空
    • 返回队列中的队头元素
    • 返回队列中的队尾元素
    • 队列的一个演示过程
    • 全部代码
      • Queue.h
      • Queue.c
      • Test.c

栈的基本概念

数据结构-栈和队列_第1张图片

我们选用数组的形式来构成栈

栈的结构

以一个结构体的形式来表示栈的一些信息

typedef struct Stack
{
	STDataType* a;
	int top;//表示栈顶位置,也表示已存储的数据个数
	int capacity;//
}ST;

初始化栈

初始化结构体的各个成员,对指针所在位置开辟空间

void STInit(ST* ps)
{
	assert(ps);

	ps->a=(STDataType*)malloc(sizeof(STDataType)*4);
	if(ps->a==NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->top = 0;
	ps->capacity = 4;
}

销毁栈

对于malloc函数开辟的空间要释放掉,其它置0

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

压栈

空间不够,先开辟空间;给数据,然后top++

void STPush(ST* ps,STDataType x)
{
	assert(ps);

	if (ps->top==ps->capacity)
	{
		STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
		if (temp==NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = temp;
		ps->capacity = ps->capacity * 2;
	}

	ps->a[ps->top] = x;
	ps->top++;
}

出栈

只需要动top的值即可,但是要确保栈中存在元素,用一个函数STEmpty来判断

bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top==0;
}
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;
}

栈中元素的个数

直接返回top

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

查找栈顶的元素

要先判断栈中是否含有元素,直接返回栈顶的元素(此处的top已经是++之后的,所以需要-1)

STDataType STTop(ST* ps)
{ 
	assert(ps);
	assert(!STEmpty(ps));

	return ps->a[ps->top-1];
}

压栈和出栈的一个演示

如下:

int main()
{
	ST plist;
	STInit(&plist);
	STPush(&plist, 1);
	STPush(&plist, 2);
	STPush(&plist, 3);
	STPop(&plist);
	STPush(&plist, 4);

	//打印方式,先返回栈顶的元素,再出栈
	while (!STEmpty(&plist))
	{
		printf("%d ", STTop(&plist));
		STPop(&plist);
	}

	STDestroy(&plist);
	return 0;
}

结果如下:
在这里插入图片描述

全部代码

Stack.h

#pragma once
#include 
#include 
#include 
#include 

typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//表示栈顶位置,也表示已存储的数据个数
	int capacity;//
}ST;

void STInit(ST* ps);
void STDestroy(ST* ps);

//压栈
void STPush(ST* ps,STDataType x);
//出栈
void STPop(ST* ps);

bool STEmpty(ST* ps);

//栈中元素的个数
int STSize(ST* ps);

//查找栈顶的元素
STDataType STTop(ST* ps);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Stack.h"

void STInit(ST* ps)
{
	assert(ps);

	ps->a=(STDataType*)malloc(sizeof(STDataType)*4);
	if(ps->a==NULL)
	{
		perror("malloc fail");
		return;
	}
	ps->top = 0;
	ps->capacity = 4;
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->a);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

void STPush(ST* ps,STDataType x)
{
	assert(ps);

	if (ps->top==ps->capacity)
	{
		STDataType* temp=(STDataType*)realloc(ps->a, sizeof(STDataType) * ps->capacity * 2);
		if (temp==NULL)
		{
			perror("realloc fail");
			return;
		}
		ps->a = temp;
		ps->capacity = ps->capacity * 2;
	}

	ps->a[ps->top] = x;
	ps->top++;
}


bool STEmpty(ST* ps)
{
	assert(ps);

	return ps->top==0;
}
void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

STDataType STTop(ST* ps)
{ 
	assert(ps);
	assert(!STEmpty(ps));

	return ps->a[ps->top-1];
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Stack.h"

int main()
{
	ST plist;
	STInit(&plist);
	STPush(&plist, 1);
	STPush(&plist, 2);
	STPush(&plist, 3);
	STPop(&plist);
	STPush(&plist, 4);

	//打印方式,先返回栈顶的元素,再出栈
	while (!STEmpty(&plist))
	{
		printf("%d ", STTop(&plist));
		STPop(&plist);
	}

	STDestroy(&plist);
	return 0;
}

队列

队列的基本概念

数据结构-栈和队列_第2张图片

用单链表的方式来实现队列
基本组成元素为链表的单个节点,由于队列的性质,需要知道队头和队尾,同时我们还想知道队列中元素的个数
单个节点属于队列的局部,而队头和队尾属于队列,地位处于节点之上,这种情况下需要用结构体嵌套来表示

节点和队列的定义

//单个节点
typedef struct QueneNode
{
	struct QueneNode* next;
	QDataType data;
}QNode;

//整个队列
typedef struct Quene
{
	QNode* head;
	QNode* tail;
	int size;
}Quene;

队列的初始化

需要对pq进行断言,因为当pq所指向的空间为空时,其嵌套的结构体QNode将不存在,这不符合队列的要求。只对队列结构体初始化

void QueueInit(Quene* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

销毁队列

同销毁链表一致,同时head和tail置空,size置0

void QueueDestroy(Quene* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

入队

申请一个新的节点,并对节点初始化,之后尾插

void QueuePush(Quene* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode==NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->next = NULL;
	newnode->data = x;

	//需要判断队列中是否有元素
	if (pq->head==NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}

出队

要保证队列中有元素,之后头删

void QueuePop(Quene* pq)
{
	assert(pq);//确保有队列
	assert(pq->head != NULL);//确保队列不为空

	if (pq->head->next==NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

计算队列中元素的个数

直接返回结构体中的size

int QueueSize(Quene* pq)
{
	assert(pq);

	return pq->size;
}

判断队列是否为空

bool QueueEmpty(Quene* pq)
{
	assert(pq);

	return pq->size==0;
}

返回队列中的队头元素

要确保队列中有元素

QDataType QueueFront(Quene* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

返回队列中的队尾元素

要确保队列中有元素

QDataType QueueBack(Quene* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

队列的一个演示过程

int main()
{
	Quene q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePop(&q);
	QueuePush(&q, 3);
	

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}


	QueueDestroy(&q);
	return 0;
}

结果如下:
在这里插入图片描述

全部代码

Queue.h

#pragma once
#include 
#include 
#include 
#include 

typedef int QDataType;

//单个节点
typedef struct QueneNode
{
	struct QueneNode* next;
	QDataType data;
}QNode;

//整个队列
typedef struct Quene
{
	QNode* head;
	QNode* tail;
	int size;
}Quene;

//初始化
void QueueInit(Quene* pq);
//销毁
void QueueDestroy(Quene* pq);


//入队
void QueuePush(Quene* pq, QDataType x);
//出队
void QueuePop(Quene* pq);

//计算队列中元素的个数
int QueueSize(Quene* pq);
//判断队列是否为空
bool QueueEmpty(Quene* pq);

//队列中的队头元素
QDataType QueueFront(Quene* pq);
//队列中的队尾元素
QDataType QueueBack(Quene* pq);

Queue.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Queue.h"

void QueueInit(Quene* pq)
{
	assert(pq);

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueueDestroy(Quene* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueuePush(Quene* pq, QDataType x)
{
	assert(pq);

	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode==NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->next = NULL;
	newnode->data = x;

	//需要判断队列中是否有元素
	if (pq->head==NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}

	pq->size++;
}

void QueuePop(Quene* pq)
{
	assert(pq);//确保有队列
	assert(pq->head != NULL);//确保队列不为空

	if (pq->head->next==NULL)
	{
		free(pq->head);
		pq->head = pq->tail = NULL;
	}
	else
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
	pq->size--;
}

int QueueSize(Quene* pq)
{
	assert(pq);

	return pq->size;
}

bool QueueEmpty(Quene* pq)
{
	assert(pq);

	return pq->size==0;
}

QDataType QueueFront(Quene* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->head->data;
}

QDataType QueueBack(Quene* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));

	return pq->tail->data;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "Queue.h"

int main()
{
	Quene q;
	QueueInit(&q);
	QueuePush(&q, 1);
	QueuePush(&q, 2);
	QueuePop(&q);
	QueuePush(&q, 3);
	

	while (!QueueEmpty(&q))
	{
		printf("%d ", QueueFront(&q));
		QueuePop(&q);
	}


	QueueDestroy(&q);
	return 0;
}

你可能感兴趣的:(数据结构,数据结构)