数据结构之栈和队列

目录

1.栈的概念2、栈的实现

1、队列的概念2、队列的实现

今天介绍的是栈和队列。

先说栈吧。

1.栈的概念

栈也是线性表的一种,不过他较为特殊。他只能在一边进行数据的出入。也就是说晚进的数据先出去。进行数据进出的一端叫做栈顶,另一端叫做栈底。

数据进入叫做压栈,数据出去叫做出栈。

 

从图中可以看出,栈的数据进出遵循后进先出的规则。

2、栈的实现

栈的实现可以使用数组也可使用链表。在这里我们使用数组,因为栈的数据进出本质是尾插尾删,而用链表实现,尾插与尾删还得先找到尾,相对于数组较为复杂。所以在这里选择数组。

栈有分为静态栈与动态增长的栈。

静态栈

 

在实际中相对不实用,所以在这里实现可以动态增长的栈。

这次我们实现的接口有:栈的初始化,压栈,出栈,返回栈顶数据,返回栈中数据个数,检验栈是否为空,销毁栈。

结构体创建:

typedef int Datatype;
typedef struct StackList
{
	Datatype* arr;
	Datatype top;// 初始为0,表示栈顶位置下一个位置下标
	Datatype capacity;
}SL;

初始化:

void initialize(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	slnum->arr = NULL;
}

扩容:

void expand(SL* slnum)
{
	assert(slnum);

	if(slnum->capacity == slnum->top)
	{
		Datatype newcapacity = slnum->capacity = 0 ? 4 : slnum->capacity * 2;
		SL* tmp = (SL*)realloc(slnum->arr,sizeof(Datatype) * newcapacity);
		if(tmp == NULL)
		{
			perror("realloc false");
			exit(-1);
		}
		slnum->arr = tmp;
		slnum->capacity = newcapacity;
	}
}

压栈:

void stackint(SL* slnum,Datatype n)
{
	expand(slnum);
	slnum->arr[slnum->top] = n;
	slnum->top++;
}

出栈:

void stackout(SL* slnum)
{
	assert(slnum);

	assert(slnum->top > 0);
	slnum->top--;
}

栈中元素个数:

Datatype stacktop(SL* slnum)
{
	assert(slnum);
	assert(!stackempty);
	return slnum->top-1;
}

获取栈顶:

Datatype get_stacktop(SL* slnum)
{
	assert(slnum);

	assert(!stackempty);

	return slnum->arr[slnum->top - 1];
}

检验栈是否为空:

bool stackempty(SL* slnum)
{
	assert(slnum);

	if (slnum->top > 0)
	{
		return true;
	}
	else
		return false;
}

销毁栈:

void destroy(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	free(slnum->arr);
	slnum->arr = NULL;
}

栈的介绍就到这里,下面开始介绍队列。

1、队列的概念

队列是在一端插入数据在另一端删除数据的线性表。队列的数据删除规则为先进先出。队列在队尾插入,在对头删除。

 2、队列的实现

队列的实现也可以使用数组,也可以使用链表,又因为使用数组实现队列时删除数据需要挪动数据因此在这里我们使用链表来实现队列。

因为我们在实现队列时需要在队头出队,在队尾入队。所以我们可以再次封装一个结构体变量,里面放入一个head指针,一个tail指针。

typedef int Qdatatype;
typedef struct QueueNode
{
	Qdatatype n;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

接口实现:

初始化:

void QInit(struct Queue* p)
{
	assert(p);
	p->head = NULL;
	p->tail = NULL;

	p->size = 0;

}

队尾入队列:

void Queueint(Queue* p,Qdatatype n)
{
	assert(p);

	QNode* tmp = (QNode*)malloc(sizeof(QNode));

	QNode* tmp = (QNode*)malloc(p, sizeof(QNode));

	if(tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	tmp->n = n;
	tmp->next = NULL;
	p->size++;
	if( p->tail == NULL)
	{
		p->head = p->tail = tmp;
	}
	else
	{
		p->tail->next = tmp;
		p->tail = p->tail->next;
	}
}

队头出队列:

void Queueout(Queue* p)
{
	assert(p);
	assert(!Queueempty(p));
	if(p->head->next == NULL)
	{
		free(p->head);
		p->head = p->tail = NULL;
	}
	else
	{
		QNode* tmphead = p->head;
		p->head = p->head->next;
		free(tmphead);
	}
	
	p->size--;

}

判断队列是否为空:

bool Queueempty(Queue* p)
{
	return p->head == NULL&&p->tail == NULL;
}

获取队头数据:

Qdatatype Gettop(Queue* p)
{
	assert(p);

	assert(!Queueempty(p));

	assert(!queueempty(p));

	printf("%d ", p->head->n);
}

获取队尾数据:

Qdatatype Gettail(Queue* p)
{
	assert(p);

	assert(!Queueempty(p));

	assert(!queueempty(p));

	printf("%d ", p->tail->n);
}

有效数据个数:

Qdatatype Count(Queue* p)
{
	return p->size;
}

销毁队列:

void destroy(Queue* p)
{
	assert(p);
	QNode* cur = p->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	free(p->head);
	free(p->tail);


}

3、完整版代码

栈:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int Datatype;
typedef struct StackList
{
	Datatype* arr;
	Datatype top;// 初始为0,表示栈顶位置下一个位置下标
	Datatype capacity;
}SL;

//接口功能实现
//初始化
void initialize(SL* slnum);
//扩容
void expand(SL* slnum);
//入栈
void stackint(SL* slnum,Datatype n);
//出栈
void stackout(SL* slnum);
//获取栈有效元素个数
Datatype stacktop(SL* slnum);
//获取栈顶元素
Datatype get_stacktop(SL* slnum);
//检查栈是否为空
bool stackempty(SL* slnum);
//销毁
void destroy(SL* slnum);
#pragma once
#include"stacklist.h"
void initialize(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	slnum->arr = NULL;
}
void expand(SL* slnum)
{
	assert(slnum);

	if(slnum->capacity == slnum->top)
	{
		Datatype newcapacity = slnum->capacity = 0 ? 4 : slnum->capacity * 2;
		SL* tmp = (SL*)realloc(slnum->arr,sizeof(Datatype) * newcapacity);
		if(tmp == NULL)
		{
			perror("realloc false");
			exit(-1);
		}
		slnum->arr = tmp;
		slnum->capacity = newcapacity;
	}
}
void stackint(SL* slnum,Datatype n)
{
	expand(slnum);
	slnum->arr[slnum->top] = n;
	slnum->top++;
}
void stackout(SL* slnum)
{
	assert(slnum);

	assert(slnum->top > 0);
	slnum->top--;
}
Datatype stacktop(SL* slnum)
{
	assert(slnum);
	assert(!stackempty);
	return slnum->top-1;
}
Datatype get_stacktop(SL* slnum)
{
	assert(slnum);

	assert(!stackempty);

	return slnum->arr[slnum->top - 1];
}
bool stackempty(SL* slnum)
{
	assert(slnum);

	if (slnum->top > 0)
	{
		return true;
	}
	else
		return false;
}
void destroy(SL* slnum)
{
	assert(slnum);

	slnum->capacity = 0;
	slnum->top = 0;
	free(slnum->arr);
	slnum->arr = NULL;
}

队列:

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

typedef int Qdatatype;
typedef struct QueueNode
{
	Qdatatype n;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Queue;

//初始化
void QInit(struct Queue* p);
// 队尾入队列
void Queueint(Queue* p, Qdatatype n);
// 队头出队列
void Queueout(Queue* p);
// 获取队列头部元素
Qdatatype Gettop(Queue* p);
// 获取队列队尾元素
Qdatatype Gettail(Queue* p);
// 获取队列中有效元素个数
Qdatatype Count(Queue* p);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool Queueempty(Queue* p);
// 销毁队列
void destroy(Queue* p);
#include"queue.h"
void QInit(struct Queue* p)
{
	assert(p);
	p->head = NULL;
	p->tail = NULL;
<<<<<<< HEAD
	p->size = 0;
=======
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
}
void Queueint(Queue* p,Qdatatype n)
{
	assert(p);
<<<<<<< HEAD
	QNode* tmp = (QNode*)malloc(sizeof(QNode));
=======
	QNode* tmp = (QNode*)malloc(p, sizeof(QNode));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	if(tmp == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	tmp->n = n;
	tmp->next = NULL;
	p->size++;
	if( p->tail == NULL)
	{
		p->head = p->tail = tmp;
	}
	else
	{
		p->tail->next = tmp;
		p->tail = p->tail->next;
	}
}
bool Queueempty(Queue* p)
{
	return p->head == NULL&&p->tail == NULL;
}
void Queueout(Queue* p)
{
	assert(p);
	assert(!Queueempty(p));
	if(p->head->next == NULL)
	{
		free(p->head);
		p->head = p->tail = NULL;
	}
	else
	{
		QNode* tmphead = p->head;
		p->head = p->head->next;
		free(tmphead);
	}
	
	p->size--;

}
Qdatatype Gettop(Queue* p)
{
	assert(p);
<<<<<<< HEAD
	assert(!Queueempty(p));
=======
	assert(!queueempty(p));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	printf("%d ", p->head->n);
}
Qdatatype Gettail(Queue* p)
{
	assert(p);
<<<<<<< HEAD
	assert(!Queueempty(p));
=======
	assert(!queueempty(p));
>>>>>>> 5b9085118240e85a5ef7699a109d637576c62395
	printf("%d ", p->tail->n);
}
Qdatatype Count(Queue* p)
{
	return p->size;
}
void destroy(Queue* p)
{
	assert(p);
	QNode* cur = p->head;
	while(cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}

	free(p->head);
	free(p->tail);


}

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值