数据结构—C语言实现栈和队列

目录

1栈

1.1概念与结构

1.2栈的结构

1.3栈的初始化和销毁

1.3.1初始化

1.3.2销毁

1.4栈的插入

1.5栈的删除  

 1.6获取栈顶元素

1.7获得栈里有效元素的个数

1.8实现栈的总代码 

1.8.1stack.h

1.8.2stack.c

2队列 

2.1概念与结构

2.2 队列的结构

2.3队列的初始化 

2.4队列的插入

2.5队列的删除 

2.5.1队列的判空

 2.5.2队列的删除

2.6得到队头元素

2.7得到队尾元素

2.8得到队列的有效元素个数 

2.9队列的销毁 

2.10实现队列的总代码

2.10.1Queue.h

2.10.2Queue.c 

 


 

1栈

1.1概念与结构

栈:一种特殊的线性结构,其只允许在固定的一端进行插入和删除元素操作,进行数据插入和删除操作的一端称为栈顶,另一端称为栈底,栈中的元素数据遵守后进先出的原则。

压栈:栈的插入操作叫做进栈/入栈/压栈,入数据在栈顶。

出栈:栈的删除操作叫做出栈,出数据也在栈顶。

1.2栈的结构

typedef struct stack
{
	int* arr;
	int capacity;
	int top;
}st;

1.3栈的初始化和销毁

1.3.1初始化

void stinit(st* ps)
{
	assert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}

1.3.2销毁

void stdestroy(st*ps)//销毁
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->top = ps->capacity = 0;
}

1.4栈的插入

如果空间已满,则申请2倍的空间,在进行插入。

void stpush(st* ps, int x)//插入
{
	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4: 2 * ps->capacity;
		int* tmp = (int*)realloc(ps->arr, sizeof(int) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
	ps->arr[ps->top++] = x;

}

1.5栈的删除  

如果栈不为空,top减一,实现逻辑删除。

//判空函数
bool stempty(st* ps)
{
	assert(ps);
	return ps->top == 0;
}
//删除函数
void stpop(st* ps) 
{
	assert(ps);
	assert(!stempty(ps));
    --ps->top;
}

 1.6获取栈顶元素

int sttop(st* ps)
{
	assert(ps);
	assert(!stempty(ps));
	return ps->arr[ps->top - 1];
}

1.7获得栈里有效元素的个数

int stsize(st* ps)
{
	assert(ps);
	return ps->top;
}

1.8实现栈的总代码 

1.8.1stack.h

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct stack
{
	int* arr;
	int capacity;
	int top;
}st;
void stinit(st* ps);//初始化
void stdestroy(st* ps);//销毁
void stpush(st* ps, int x);//插入
bool stempty(st* ps);//判断栈是否为空
int stsize(st* ps);//得到栈此时有效元素的个数
int sttop(st* ps);//得到栈顶的元素

1.8.2stack.c

#include"stack.h"
void stinit(st* ps)//初始化
{
	assert(ps);
	ps->arr = NULL;
	ps->capacity = ps->top = 0;
}
void stdestroy(st*ps)//销毁
{
	assert(ps);
	if (ps->arr)
		free(ps->arr);
	ps->arr = NULL;
	ps->top = ps->capacity = 0;
}
void stpush(st* ps, int x)//插入
{
	if (ps->capacity == ps->top)
	{
		int newcapacity = ps->capacity == 0 ? 4: 2 * ps->capacity;
		int* tmp = (int*)realloc(ps->arr, sizeof(int) * newcapacity);
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
	ps->arr[ps->top++] = x;

}
bool stempty(st* ps)
{
	assert(ps);
	return ps->top == 0;
}
void stpop(st* ps) 
{
	assert(ps);
	assert(!stempty(ps));
    --ps->top;
}
int sttop(st* ps)
{
	assert(ps);
	assert(!stempty(ps));
	return ps->arr[ps->top - 1];
}
int stsize(st* ps)
{
	assert(ps);
	return ps->top;
}

2队列 

2.1概念与结构

只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出。

入队:进行插入操作的一端称为队尾。

出队:进行删除操作的一端称为对头。

2.2 队列的结构

我们用链表来实现队列,包括结点结构和队列的结构。

结点结构包括:要储存的数据和指向下一个结点的指针;

队列的结构包括:头指针:用来出数据;尾指针:用来出数据。size:记录队列中元素的个数。

代码:

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;//保存队列有效数据个数
}Queue;

2.3队列的初始化 

主要是将头指针和尾指针置为NULL,将size置为0.

void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

2.4队列的插入

先创建新结点,储存数据,若队列为空,则头结点和尾结点同时指向新结点;

否则,进行将新结点插到尾结点后面,则新结点为新的尾结点。

void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode*newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;
}

2.5队列的删除 

2.5.1队列的判空

要对队列进行数据删除,要保证队列不为空,因此就要用到队列判空函数。

bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead==NULL && pq->ptail==NULL;
}

 2.5.2队列的删除

注意点:若队列中只有一个结点,进行头删后,队列为空,为避免尾结点成为野指针,因此要分类讨论。

如果只有一个结点,删除后,头尾结点都要置为NULL;

若超过一个结点,则进行头删。

void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}

2.6得到队头元素

QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}

2.7得到队尾元素

QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->ptail->data;
}

2.8得到队列的有效元素个数 

int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}

2.9队列的销毁 

void QueueDestroy(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

2.10实现队列的总代码

2.10.1Queue.h

#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
#include<stdio.h>
typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QueueNode;
typedef struct Queue
{
	QueueNode* phead;
	QueueNode* ptail;
	int size;//保存队列有效数据个数
}Queue;
void QueueInit(Queue* pq);
void QueuePush(Queue* pq, QDataType x);// ?队列,队尾
void QueuePop(Queue* pq);// 出队列,队头
bool QueueEmpty(Queue* pq);//队列判空
QDataType QueueFront(Queue* pq);//取队头数据
QDataType QueueBack(Queue* pq);//取队尾数据
int QueueSize(Queue* pq);//队列有效元素个数
void QueueDestroy(Queue* pq);//销毁队列

2.10.2Queue.c 

#include"Queue.h"
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QueueNode*newnode = (QueueNode*)malloc(sizeof(QueueNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->phead == NULL)
	{
		pq->phead = pq->ptail = newnode;
	}
	else
	{
		pq->ptail->next = newnode;
		pq->ptail = pq->ptail->next;
	}
	pq->size++;
}
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->phead==NULL && pq->ptail==NULL;
}
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	if (pq->phead == pq->ptail)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QueueNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}
	pq->size--;
}
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->phead->data;
}
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->ptail->data;
}
int QueueSize(Queue* pq)
{
	assert(pq);
	return pq->size;
}
void QueueDestroy(Queue* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	QueueNode* pcur = pq->phead;
	while (pcur)
	{
		QueueNode* next = pcur->next;
		free(pcur);
		pcur = next;
	}
	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

 

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值