C语言数据结构第三章—— 数组实现的队列

C语言数据结构第三章—— 数组实现的队列

get 到的东西:

队列是先进先出的,数据从队列的一端进,另一端出;
要注意当一次输入/删除完成后,各个控制变量的值对应的队列状态!

  • 控制参数多了,写这个的时候我炸了,最后发现是基础逻辑错了QAQ…
  • 在写程序的时候,要知道每个参数的对应情况最后状态

实现流程

需要设置的控制参数有:

  1. top(队列中的队头元素,也是最先出去的)
  2. rear(队列中的队尾元素,也是最慢出去的)
    由于这样子的队列会让top和rear一直往后走,造成内存浪费,所以可以让top/rear到一定的值max时,回到数组的0位置继续存储数据。
  3. max(数组的最后一位)并且可以用来计算队列是否超出了承载范围,超出了的话可以再申请空间
  4. amount 数组数字数量,看看有多少数字在队列里

需要写的函数有:

  1. 先申请5个int空间做数组,申请到的地址直接当数组用就行
  2. 初始化,scanf读到-1就结束,在输入data的时候把rear也往后推
    • 空数组和只有一个数字的数组的top和rear是一样的,那再加个amount吧
    • 如果空间不够的话,再申请地址,然后把max改了
  3. 前边第一个数出队列 dequeue
  4. 后边再进个数在队列末尾 enqueue
    • 输入的时候要考虑的东西还是挺多的~
  5. 输出队列的函数,如果到数组尾巴了还没输出完,那就是又回去了

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函数内的内存大小是赋完全部值的大小,不是变大的大小。

图片1

  • 应该是申请完后新入列的数没有到新增的数组位置中,直接按照原来的数组大小回去了
    …在输入数据后没有马上让amount+1,在最后才+1的,然后就有了一个时间差…
    图片2

图片3

  • 问题是申请了内存空间之前rear就变成0 了,所以申请的五个空间没人用
    !!!这个思路从一开始就是错的…拓展的内存在数组后边,不能成为闭环队列
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值