拔丝芋头的数据结构复习日记---Day2---堆栈、队列

2023-10-29 14:10

本文主要是介绍拔丝芋头的数据结构复习日记---Day2---堆栈、队列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

< 今日知识点 >

  • 堆栈
  • 队列

·
·
·

—01 堆栈

在这里插入图片描述

1、栈的顺序存储实现

#define MAXSIZE  //储存数据元素的最大个数
typedef struct SNode *Stack;
struct SNode{ElementType Data[MAXSIZE];int top;
};
  • 栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成
  • 当栈为空时,通常初始化栈顶元素位置变量top为-1

2、栈的操作实现
(1)入栈

void Push(Stack S,ElementType X)
{if(S->top == MAXSIZE-1){printf("堆栈满");return ;}else{S->Data[++(S->top)] = X;return ;}
}

(2) 出栈

ElementType Pop(Stack S)
{if(S->top == -1){printf("堆栈空");return Error;   //ERROR是ElementType的特殊值,标志错误} else {return(S->Data[(S->top)--]);}
}


例子:在这里插入图片描述

-分析:一种比较聪明的方法是使这两个栈分别从数组的两头开始向中间生长,当两个栈的栈顶指针相遇时,就表示两个栈都满了

代码实现:

#define MAXSIZE   <储存数据元素的最大个数>
struct DStack{ElementType Data[MAXSIZE];int top1;int top2;
}S;
//初始化:
S.top==-1;
S.top2==MAXSIZE;

入栈操作:

void Push(struct DStack *S,ElementType item,int tag)
{if(S->top2 - S->top1 == 1){printf("堆栈已满");return ;}if(tag==1)     //对第一个堆栈进行操作S->Data[++(S->top1)] = item;else S->Data[--(S->top2)] = item;
}

出栈操作:

ElementType Pop(struct DStack *S,int tag)
{if(tag==1){if(S->top1==-1) {printf("堆栈1空");return NULL;else return S->Data[(S->top1)--];}else{if(S->top2==MAXSIZE){printf("堆栈2空");return NULL;else return S->Data[(S->top2)++];}
}
  • tag作为区分两个堆栈的标志,取值为1和2

3、堆栈的链式存储实现

typedef struct SNode *Stack;
struct SNode{ElementType *Data;struct SNode *Next;
};
  • 栈的链式存储结构实际上就是一个单链表,叫做栈链。插入和删除操作只能在栈链的栈顶进行。
  • 栈顶指针top应该在链表的哪一头? (应该在链表头的位置

4、栈的链式存储操作:
(1)堆栈初始化(建立空栈)

Stack CreateStack()
{Stack S;S = (Stack)malloc(sizeof(struct SNode));S->Next = NULL;return S;
}
  • 即堆栈的一个头结点,返回指针

(2) 判断堆栈是否为空

int IsEmpty(Stack S)
{return (S->Next == NULL)
  • 判断堆栈是否为空,若为空返回整数1,否则返回0

(3) 入栈

void Push(ElementType item,Stack S)
{struct SNode *TmpCell;TmpCell = (struct SNode*)malloc(sizeof(struct SNode));TmpCell->Element = item;TmpCell->Next = S->Next;S->Next = TmpCell;
}

(4) 出栈

ElementType Pop(Stack S)         
{      //删除并返回栈顶的元素struct SNode *FirstCell;ElementType topItem;if(IsEmpty(S)){printf("堆栈空");return NULL;}else {FirstCell = S->Next;S->Next = FirstCell -> Next;topItem = FirstCell -> Element;free(FirstCell);return topItem;}
}

5、堆栈应用:表达式求值
在这里插入图片描述

中缀表达式求值

基本策略:将中缀表达式转换为后缀表达式 (如何转换?)
观察一个简单例子:2+9 /3 -5 -> 2 9 3 / + 5 -
总结:
1、运算数相对顺序不变
2、运算符号顺序发生改变

  • 需要存储等待中的运算符号
  • 需要将当前运算符号与 等待中 的最后一个运算符 比较

在这里插入图片描述

中缀表达式如何转换为后缀表达式

-----> 从头到尾读取中缀表达式的每个对象,对每个对象按不同的情况处理
1、运算数:直接输出
2、左括号:压入堆栈
3、右括号:将栈顶的运算符弹出并输出,直到遇到左括号(出栈,不输出)
4、运算符:

  • 优先级大于栈顶运算符时,则把它压栈
  • 优先级小于栈顶运算符时,将栈顶运算符弹出并输出。再比较新的栈顶运算符,直到运算符大于栈顶运算符优先级为止,然后将该运算符压栈。
    5、若各对象处理完毕,则把堆栈中存留的运算符一并输出。在这里插入图片描述

·
·
·

—02 队列

1、
在这里插入图片描述

代码:

#define MAXSIZE  <储存数组元素的最大个数>
struct QNode{ElementType Data[MAXSIZE];int front;int rear;
};
typedef struct QNode *Queue;
  • 队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量以及一个记录队尾元素位置的变量rear组成

2、 循环队列

在这里插入图片描述

思考题:
  • 堆栈空的判别条件是front==rear ,堆栈满的判别条件是(rear+1)%MAXSIZE == 0
  • 出现空、满无法区分的原因:堆栈可能出现的情况有七种,即空,和存在1、2、3、4、5、6个元素,而下标数字只有六种情况,即0~5,所以六个数字情况是无法不重复地表示堆栈的所有情况的,需要寻找新的表示方法

3、队列的操作
(1)入队列

void AddQ(Queue Q,ElementType item)
{ if(Q->rear+1)%MAXSIZE==Q->front){printf("队列满");return ;}Q->rear = (Q->rear+1% MAXSIZE;Q->Data[Q->rear] =item;
}

(2) 出队列

ElementType DeleteQ (Queue Q)
{if(Q->front == Q->rear){printf("队列空");return ERROR;}else{Q->front = (Q->front+1)%MAXSIZE;return Q->Data[Q->front];}
}
- front和rear指针的移动采用 加1取余 法,体现了顺序存储的循环使用特性。

4、队列的链式存储实现

  • 队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行;
  • 思考:队列指针front和rear应该分别指向链表的哪一头??
  • (front进行的是删除操作,应该指向链表头,rear进行的是插入操作,应该指向链表尾。因为对front来说,如果指向的是链表尾,那么一旦删除了一个元素,就找不到其他的元素了,即丢失了)
struct Node{ElementType Data;struct Node *Next;
};struct QNode{        //链队列结构 struct Node *rear;         //指向队尾和队头节点struct Node *front;
}typedef struct QNode *Queue;
Queue Q;

在这里插入图片描述

  • 不带头结点的链式队列出队操作的一个示例:
ElementType DeleteQ(Queue Q)
{	struct Node *frontCell;ElementType frontElem;if(Q->front ==NULL){printf("队列空");return ERROR;}frontCell = Q->front;if(Q->front == Q->rear)       //若队列中只有一个元素,删除后 队列置为空Q->front = Q->rear =NULL;else Q->front = Q->front->Next;frontElem = frontCell->Data;free(frontCell);return frontElem;
}

·
·
·
附:文中所有PPT图片均来自中国大学mooc 浙江大学《数据结构》课程!!

这篇关于拔丝芋头的数据结构复习日记---Day2---堆栈、队列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/301175

相关文章

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

Spring Boot整合消息队列RabbitMQ的实现示例

《SpringBoot整合消息队列RabbitMQ的实现示例》本文主要介绍了SpringBoot整合消息队列RabbitMQ的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录RabbitMQ 简介与安装1. RabbitMQ 简介2. RabbitMQ 安装Spring

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

poj 3190 优先队列+贪心

题意: 有n头牛,分别给他们挤奶的时间。 然后每头牛挤奶的时候都要在一个stall里面,并且每个stall每次只能占用一头牛。 问最少需要多少个stall,并输出每头牛所在的stall。 e.g 样例: INPUT: 51 102 43 65 84 7 OUTPUT: 412324 HINT: Explanation of the s