-
Notifications
You must be signed in to change notification settings - Fork 0
/
day 07 - new - plus
43 lines (36 loc) · 4.02 KB
/
day 07 - new - plus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
// 线性结构的两种常见应用之二 - 队列 - 可以这样理解,把正常线性表竖起来(这里可以不看-上面叫首结点,下面叫尾结点),(针对循环队列)不过下标小的在最下面(因为栈是先存低地址在存高地址的),最下面要么加入要么删除,最上面要么删除要么加入(反正要定一个方向)
// 定义
// 一种可以实现"先进先出"的存储结构 - 一端插入元素,一端进行删除
// 类似于过安检门,只能从一个方向走向另一个方向,不能反着走,只能正着走(就是只能在一端入,一端出)
//
// 分类(指向第一个(front),指向最后一个的下一个元素(rear)(也就指向"头节点"))(队列没有固定的出队和入队。)
// 链式队列(链表) - 加的化是头插,删的话是尾删,如果要删除元素尾删,加入元素头插 - 链表好弄,因为链表的空间是无限的,你创建一个系统给你一个,释放一个还给系统一个。不用考虑空间,不像静态队列是一块空间
// 静态队列(数组) - 加的化是头插,删的话是尾删,如果要删除元素尾删,加入元素头插 - 静态队列一般是用循环队列来实现的(静态队列通常都必须是循环队列)
//
// 循环序列讲解 - 链表好弄,因为链表的空间是无限的,你创建一个系统给你一个,释放一个还给系统一个。不用考虑空间,不像静态队列是一块空间
// 静态队列为什么必须是循环队列 - 因为数组是一块空间,删除一个元素那这块空间就无法再次访问 - 添加元素时入队指针向向前指向新加的元素(因为时数组),同样删除元素时出队指针向前一个指去。而删除的数组就无法访问,这就是传统的静态队列,这就是它的缺陷 - 只能增不能减,浪费空间
// 所以循环队列解决了这个问题(把最上面和最下面给连接起来解决了浪费空间的问题,就会在一块空间里循环下去)
// 循环队列需要几个参数来确定
// 2个参数 -(不同场合有不同含义) 指向第一个(front),指向最后一个的下一个元素(rear)(也就指向"头节点")。解释下:这只是某些场合用。建议初学者先记住,以后慢慢体会
// 循环队列各个参数的含义
// 初始化 - font和rear的值都为0
// 非空 - font代表的是队列的第一个元素,rear代表的是队列最后一个有效元素的下一个元素
// 队列空 - font和rear的值相等,但不一定是0
// 循环队列入队伪算法讲解
// 新元素存入在rear的位置。
// 然后rear指向的位置+1,但不能超出这个数组长度。所以r = (r+1)%数组的长度,可以循环起来(一开始front和rear相等,入队在r放了一个值,然后r指向下一个元素地址,正好也给f放了个元素)
// 循环队列出队伪算法
// 删除元素删的front的位置,但是free直接数组断了,我们循环队列看的是rear位置前一个到font的内容(也就是看的是效数据),所以移动下一位就可以了但是还是不能超过这个数组的长度
// 所以所以front = (front+1)%数组的长度,可以循环起来
// 如何判断循环队列是否为空
// 如果front与rear的值相等,则队列一定为空
// 如何判断循环队列是否已满
// 判断谁大谁小是看下标,但是因为是循环队列,是循环的所以大小没有规律
// 当rear指向front指向的元素循环为满,但是如果循环中全放一样的元素呢。2种办法:1数组长度计数器(多增加一个标志参数),2少一个元素,rear走一步判断
// 通常用的是第2种方法,牺牲1个元素,所以最多放n-1个有效元素 - 所以走一步判断一次
// 如果r和f的值紧挨着,队列已满 - 因为rear和front之间没有规律
// if((r+1)%数组长度==f)满了//这里是 == f指向的地址,地址是唯一的,所以可以