数据结构之栈与队列的实现与详细解析

这篇具有很好参考价值的文章主要介绍了数据结构之栈与队列的实现与详细解析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:点我进入主页

专栏分类:C语言初阶      C语言程序设计————KTV       C语言小游戏     C语言进阶

C语言刷题       数据结构初阶

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂。

目录

1.前言

2.栈

2.1栈的概念与性质

2.2栈的实现

3.队列

3.1队列的概念

3.2队列的实现

4.练习

4.1编程

4.2概念


1.前言

        在前面我们写了关于链表和顺序表的内容,我们很容易知道顺序表相当于数组,链表是不连续的空间连在一起,顺序表和链表是我们学习数据结构的一个重要的基础,今天我们主要讲解的是两个重要的结构栈和队列,这两个结构既可以使用顺序表实现也可以使用链表实现,顺序表和链表哪一个更好呢?这需要我们知道栈和队列是如何进行数据的存储的,这与他们数据存储的性质有关,接下来让我们看看栈与队列的具体实现吧。

2.栈

2.1栈的概念与性质

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶

栈满足数据的先进后出的原则,例如我们让1,2,3,4,5依次入栈,我们出栈先出栈的是数字5。既然栈是先进后出我们用数组进行数据的存储还是用链表进行数据的存储呢,先进后出也就是说我们呢访问需要栈知道栈顶的位置,但是我们在数据入栈时链表相对来说比较困难,所有我们在选择栈的存储时一半使用数组。

2.2栈的实现

        在栈的操作中,我们包括栈的初始化,入栈,出栈,栈空,增容,取栈顶元素,栈中元素个数,遍历,释放空间这几个操作。

void InItStack(Stack* s)
{
    assert(s);
    s->capacity = 4;
    s->top = -1;
    s->data = (char*)malloc(sizeof(char) * s->capacity);
}
void CheckCapacity(Stack* s)
{
    assert(s);
    if (s->top + 1 == s->capacity)
        s->capacity += 2;
    char* p = (char*)realloc(s->data, sizeof(char) * s->capacity);
    if (p == NULL)
    {
        perror("realloc fail");
        return;
    }
    else
        s->data = p;
}
void StackPush(Stack* s, char ch)
{
    assert(s);
    CheckCapacity(s);
    s->data[++s->top] = ch;
}
bool StackEmpty(Stack* s)
{
    assert(s);
    if (s->top == -1)
        return true;
    return false;
}
char StackPop(Stack* s)
{
    assert(s);
    if (!StackEmpty(s))
    {
        s->top--;
        return s->data[s->top + 1];
    }
    return '1';
}
void StackDestory(Stack* s)
{
    assert(s);
    free(s->data);
}
int StackSize(Stack* s)
{
    assert(s);
    return s->top + 1;
}
int StackTopdata(Stack* s)
{
    assert(s);
    return s->data[s->top];
}

        在函数实现时我们有几点需要注意,首先我们需要将栈顶初始化为-1,主要原因是如果我们初始化为0的话,栈为空判断起来比较麻烦,初始化为-1就很容易判断。还有就是当我们操作执行完后我们需要将空间进行释放。

3.队列

3.1队列的概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头。队列也可以数组和链表的结构实现,使用链表的结构实现更优一些,因为如果使用数组的结构,出队列在数组头上出数据,效率会比较低。

3.2队列的实现

        在队列的操作中我们包括对队列的初始化,队列节点的创建,出队,入队,取队顶元素,对空,遍历,队列元素个数,释放空间。

typedef struct QNode {
	int data;
	struct QNode* next;
}QNode;
typedef struct Queue {
	struct QNode* head;
	struct QNode* tail;
}Queue;
void QueueInit(Queue* q)
{
	assert(q);
	q->head = NULL;
	q->tail = NULL;
}
QNode* QueueCreate(Queue* q, int x)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return NULL;
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
void QueuePush(Queue* q, int x)
{
	QNode* newnode = QueueCreate(q, x);
	if (q->head == NULL)
	{
		q->head = newnode;
		q->tail = newnode;
	}
	else
	{
		q->tail->next = newnode;
		q->tail = newnode;
	}
}
bool QueueEmpty(Queue* q)
{
	return q->head == NULL;
}
int QueuePop(Queue* q)
{
	assert(q);

	if (!QueueEmpty(q))
	{
		int data = q->head->data;
		if (q->head == q->tail)
		{

			free(q->head);
			q->head = q->tail = NULL;
		}
		else
		{
			QNode* cur = q->head->next;
			free(q->head);
			q->head = cur;
		}
		return data;
	}
}
int QueueSize(Queue* q)
{
	int count = 0;
	QNode* cur = q->head;
	while (cur)
	{
		count++;
		cur = cur->next;
	}
	return count;
}
void QueueDestory(Queue* q)
{
	assert(q);
	if (!QueueEmpty(q))
	{
		QNode* cur = q->head->next;
		QNode* prev = q->head;
		while (prev)
		{
			free(prev);
			prev = cur;
			if (cur)
			{
				cur = cur->next;
			}
		}
	}
}
void QueuePrint(Queue* q)
{
	assert(q);
	QNode* cur = q->head;
	while (cur)
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
}
int top(Queue* q)
{
	assert(q);
	if (!QueueEmpty(q))
	{
		return q->head->data;
	}
}

        在队列中我们需要注意几点,我们在传参数时传的是一级指针,我们在前面写链表时我们都是传的二级指针,而且我们也是对头指针进行操作,为什么会传一级指针呢?这主要就是我们创建了两个结构体,第一个结构体储存数据,第二个结构体储存头尾指针,我们传的时第二个结构体的地址,传结构体当然是一级指针了为什么在前面我们使用了二级指针呢?这主要是我们返回值是void类型,我们知道函数在进行传参时会将传送的参数拷贝一份,这一份也就是我们在函数中进行操作的数据,我们对指针内容进行修改,如果修改的不是头指针,不会出现任何问题,但是我们一旦修改头指针的位置,那么就会出现错误。

4.练习

4.1编程

1. 括号匹配问题。OJ链接
2. 用队列实现栈。OJ链接
3. 用栈实现队列。OJ链接
4. 设计循环队列。OJ链接

4.2概念

1.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出
栈的顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA
2.若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1
3.循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作
后, front=rear=99 ,则循环队列中的元素个数为( )
A 1
B 2
C 99
D 0或者100
4.以下( )不是队列的基本运算?
A 从队尾插入一个新元素
B 从队列中删除第i个元素
C 判断一个队列是否为空
D 读取队头元素的值
5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设
队头不存放数据)
A (rear - front + N) % N + 1
B (rear - front + N) % N
C ear - front) % (N + 1)
D (rear - front + N) % (N - 1)
 文章来源地址https://www.toymoban.com/news/detail-754594.html

到了这里,关于数据结构之栈与队列的实现与详细解析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】 栈与队列的相互实现

    队列与栈的操作算法是笔试面试中较为常见的题目。 本文将着重介绍平时面试中常见的关于队列与栈的应用题目,马上要进行秋招了。希望对你们有帮助 _😀 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现

    2024年02月10日
    浏览(44)
  • 【数据结构经典题目】—两个队列实现栈与两个栈实现队列

    ​                                           食用指南:本文在有C基础的情况下食用更佳                                            🔥 这就不得不推荐此专栏了: C语言                                         🍀

    2024年02月13日
    浏览(44)
  • 数据结构之栈和队列 - 超详细的教程,手把手教你认识并运用栈和队列

    栈:后进先出 队列:先进先出 栈:是一种特殊的 线性表 , 只允许在固定的一端插入或者删除元素 ,一个栈包含了栈顶和栈底。只能在栈顶插入或者删除元素。 栈的底层 是由 数组 实现的。 栈遵循先入后出原则,也就是先插入的元素得到后面才能删除,后面插入的元素比

    2024年02月07日
    浏览(78)
  • (详解)数据结构-----------栈与队列 c语言实现

    本章将会详细讲解以下知识点: 目录 一:栈         1:栈的定义,栈的特点         2:用什么结构来实现栈与原因的分析?         3:  (超详解)栈的常用接口并且附上测试用例 二:队列         1:队列的定义,队列的特点         2:用什么结构来实现队列与原因的分析

    2024年02月11日
    浏览(44)
  • 【栈与队列】之栈的顺序存储(图文详细介绍!!)

    前言:本章基于《大话数据结构》和王卓老师的视频内容,为刚接触数据结构的初学者提供一些帮助。 💕如果我的文章对你有帮助,点赞、收藏、留言都是对我最大的动力 目录 4.1 栈的定义 4.2 栈的抽象数据类型 4.3 栈的顺序存储结构及实现 4.4 完整代码 栈:是限定仅在表

    2024年02月03日
    浏览(29)
  • 数据结构之栈和队列

      数据结构是程序设计的重要基础,它所讨论的内容和技术对从事软件项目的开发有重要作用。学习数据结构要达到的目标是学会从问题出发,分析和研究计算机加工的数据的特性,以便为应用所涉及的数据选择适当的逻辑结构、存储结构及其相应的操作方法,为提高利用

    2024年01月22日
    浏览(46)
  • 【数据结构】线性表之栈、队列

    前面两篇文章讲述了关于线性表中的顺序表与链表,这篇文章继续讲述线性表中的 栈和队列。 这里讲述的两种线性表与前面的线性表不同,只允许在一端入数据,一段出数据,详细内容请看下面的文章。 顺序表与链表两篇文章的链接: 线性表之顺序表 线性表之链表 注意:

    2024年02月06日
    浏览(57)
  • 数据结构之栈、队列——算法与数据结构入门笔记(四)

    本文是算法与数据结构的学习笔记第四篇,将持续更新,欢迎小伙伴们阅读学习 。有不懂的或错误的地方,欢迎交流 栈是一种线性数据结构,其 只允许在固定的一端进行插入和删除 元素操作。进行数据插入和删除操作的一端称为栈顶 (Top), 另一端称为栈底 (Bottom)。栈中的

    2024年02月08日
    浏览(39)
  • 数据结构——栈与队列

    目录 一、栈 1.栈的定义  2.栈的分类与基本操作 1. 顺序栈 2.链栈 3.栈与递归的实现 1.递归的简单描述 2.递归过程及与栈的关联 3.递归过程示意图 二.队列 1.队列的定义  2.队列的分类与基本操作 1.顺序队列 2.链队列 3.循环队列 1.假溢出  2.循环队列 3.循环队列相关操作实现:

    2024年02月04日
    浏览(44)
  • 【数据结构】栈与队列

    栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元素遵守后进先出 LIFO (Last In First Out) 的原则。 压栈:栈的插入操作叫做进栈/压栈/入栈, 入数据在栈顶 。 出栈:栈的删除操

    2024年02月13日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包