C语言数据结构第三章—— 数组实现的队列
get 到的东西:
队列是先进先出的,数据从队列的一端进,另一端出;
要注意当一次输入/删除完成后,各个控制变量的值对应的队列状态!
- 控制参数多了,写这个的时候我炸了,最后发现是基础逻辑错了QAQ…
- 在写程序的时候,要知道每个参数的对应情况和最后状态
实现流程
需要设置的控制参数有:
- top(队列中的队头元素,也是最先出去的)
- rear(队列中的队尾元素,也是最慢出去的)
由于这样子的队列会让top和rear一直往后走,造成内存浪费,所以可以让top/rear到一定的值max时,回到数组的0位置继续存储数据。 - max(数组的最后一位)并且可以用来计算队列是否超出了承载范围,超出了的话可以再申请空间
- amount 数组数字数量,看看有多少数字在队列里
需要写的函数有:
- 先申请5个int空间做数组,申请到的地址直接当数组用就行
- 初始化,scanf读到-1就结束,在输入data的时候把rear也往后推
- 空数组和只有一个数字的数组的top和rear是一样的,那再加个amount吧
- 如果空间不够的话,再申请地址,然后把max改了
- 前边第一个数出队列 dequeue
- 后边再进个数在队列末尾 enqueue
- 输入的时候要考虑的东西还是挺多的~
- 输出队列的函数,如果到数组尾巴了还没输出完,那就是又回去了
C语言代码——实现部分操作
2020/2/16 数组实现的队列
#include <stdio.h>
#include <stdlib.h>
#define Size 5
//是一个不完善的数组——列表,就是在top,rear,内存的申请,max,amount的关系上没有理清楚,下次写的时候多写注释吧...
// 要注意当一次输入/删除完成后,各个控制变量的值对应的队列状态
typedef struct list{
int* head; //数组头地址
int top; //队首
int rear; //队尾
int max; //队伍最大容量
int amount; //队伍现存容量
}List;
void Init_queue(List *plist);
void Enqueue(List *plist);
void Dequeue(List *plist);
void Print_queue(List *plist);
int main()
{
List list;
Init_queue(&list);
int i=1, input=1;
for( ; ;)
{
Enqueue(&list);
Print_queue(&list);
for( i=0; i<input; i++)
{
Dequeue(&list);
if(list.amount==0){
printf("队列已空,不能再删\n");
break;
}
}
printf("max is %d\n", list.max);
printf("amount is %d\n", list.amount);
printf("top is %d\n", list.top);
printf("rear is %d\n", list.rear);
Print_queue(&list);
printf("if you want to break, print -1\n other input is used to do n turns Dequeue\n");
scanf("%d", &input);
if(input==-1) break;
}
return 0;
}
void Init_queue(List *plist) //create a array which has 5 seat
{
int *head = (int*)malloc(Size * sizeof(int));
plist->top = 0;
plist->rear = -1;
plist->amount = 0;
plist->head = head;
plist->max = Size;
}
void Enqueue(List *plist)
{
int input_data;
do{
scanf("%d", &input_data);
if(input_data != -1){ //整理一下逻辑,在输入有效时,程序的操作顺序为:
if( plist->rear == plist->max ){ // 1.数组最大坐标max-1时,如果队尾rear到了数组指示范围之外,就要当场变成0
plist->rear = 0; //对应这次数据输入的数组下标
}
else {plist->rear ++;} //如果rear没有到队尾,那继续增大。
(plist->head)[plist->rear] = input_data; //2.把数据放到数组的第rear位
plist->amount ++; //3.数组数量加一
if( plist->amount == plist->max ) //array is not enough 2.1当数量为最大存储量max-1时,申请新的空间,并把max更新
{
printf("队列排满了,得先出队才能继续入队\n");
return ;
}
}
}while(input_data != -1);
printf("Enqueue is over\n");
}
//测试输入 1 2 3 4 -1 5 6 7 8 9 10 -1 0 11 12 13 14 15 16 17 18 -1
void Dequeue(List *plist) //删除先进队伍的值
{
if( plist->top != (plist->max - 1) ) //如果列首top没到数组最大坐标max-1时,下一个top指向top+1
{
plist->top ++;
}
else{
plist->top = 0;//如果列首top到了数组最大坐标max-1时,下一个top指向0
}
plist->amount --; //删除列首(先入列的),队列数量-1
printf("Dequeue is over\n");
}
void Print_queue(List *plist) //输出队列,从top输出到rear,如果到了数组最大坐标max-1,那就转到0开始输出
{
int put = plist->top;
int print_amount = 0;
for(print_amount = 0 ; print_amount < plist->amount; print_amount++)
{
printf("queue %d is %d\n", print_amount+1, (plist->head)[put] );
if( put==plist->max-1 ) put = 0;
else {put++;}
}
}
问题日志
调试代码,理清参数直接的关系,发现逻辑有问题的过程
- 存的时候的top有问题!逻辑有问题…第一个存的时候rear不变,但是我是先存后变,造成第一个点存了两次
在数字大于Size时炸了!我看看为什么。realloc函数内的内存大小是赋完全部值的大小,不是变大的大小。
- 应该是申请完后新入列的数没有到新增的数组位置中,直接按照原来的数组大小回去了
…在输入数据后没有马上让amount+1,在最后才+1的,然后就有了一个时间差…
- 问题是申请了内存空间之前rear就变成0 了,所以申请的五个空间没人用
!!!这个思路从一开始就是错的…拓展的内存在数组后边,不能成为闭环队列