• "队列"学习


    首先是简单队列,也不多说了

    image

    使用数组结构创建队列:

    image

    队列定义代码:

    #include<stdio.h>
    
    #define MAX_SIZE 10
    
    int queue[MAX_SIZE];
    
    int rear = -1;
    int front = -1;

    队列操作代码:

    int InQueue(int value)
    {
    	if(rear >= MAX_SIZE)
    		return 0;
    	rear ++;
    	queue[rear] = value;
    	return 1;
    }
    
    int OutQueue(int *value)
    {
    	if(front == rear)
    		return 0;
    	front ++;
    	*value = queue[front];
    	return 1;
    }

    测试代码:

    void main()
    {
    	int temp;
    
    	while(1)
    	{
    		printf("1:存入;2:读取;+》:");
    		scanf("%d",&temp);
    		//清空临时缓冲区
    		fflush(stdin);
    		if(temp == 1)
    		{
    			printf("请输入要存入的值:");
    			scanf("%d",&temp);
    			fflush(stdin);
    			if(InQueue(temp) == 1)
    				printf("插入队列成功!\n");
    			else
    				printf("队列已满!\n");
    		}else if(temp == 2){
    			//取数据
    			if(OutQueue(&temp))
    			{
    				printf("读取队列值为:%d\n",temp);
    			}else
    				printf("队列为空\n");
    		}else
    			break;
    	}
    }

    接着介绍下循环队列:

    image

    上面的状态是先插入4个元素,然后全部取出,再插入5个元素的状态。这时候单向队列已经满了。

    当队尾达到边界的时候,可以发现队列已经不能再存入数据了,然而队首还有一些空的区域。

    为了弥补单队列的这个缺点,我们可以利用循环队列来实现重复利用这些空闲空间。

    image

    首先将队尾移到数据区域的头部,并且插入数据,那么空闲的区域又可以重复使用了。

    这里的插入队列函数写作:

    int InQueue(int value)
    {
    	//判断队满
    	//1.队头一个数据都没取,且队尾到了边界
    	//2.队尾已经反过来(队头已经取过数据)队尾下一个为队头
    	//事实上这里浪费了一个空间,因为我们在出数据的时候还要判断一个队空
    	//队头一直在取,去最后一个的时候队头与队尾相等,作为队空的条件
    	if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front)
    		return 0;
    	rear++;
    	if(rear == MAX_SIZE) rear = 0;
    	queue[rear] = value;
    	return 1;
    }

    下面是出队函数:


    int OutQueue(int *value)
    {
    	if(rear == front)
    		return 0;
    	front++;
    	if(front == MAX_SIZE) front = 0;
    	*value = queue[front];
    	return 1;
    
    }

    可以看到思成在这里充分考虑了两种情况,普遍情况是队尾在队首前面一位的时候,这时候不能再插入了,还有一种特殊情况会使队尾在队首前面, 那就是队尾在最后一位而队首刚好在数据域第一个的时候,条件中也排除了这种情况。(如下图)

    image

    还有一种思路,就是《严版数据结构里的》,更加简洁,将这两种情况结合起来考虑了。

    int InQueue(int value)
    {
    	//if(front == -1 && rear == MAX_SIZE - 1 || rear + 1 == front)
    	if((rear+1) % MAX_SIZE == front)
    		return 0;
    	//rear++;
    	//if(rear == MAX_SIZE) rear = 0;
    	rear = (rear + 1) % MAX_SIZE;
    	queue[rear] = value;
    	return 1;
    }

    出队列也可以相应的改成:

    int OutQueue(int *value)
    {
    	if(rear == front)
    		return 0;
    	//front++;
    	//if(front == MAX_SIZE) front = 0;
    	front = (front + 1) % MAX_SIZE;
    	*value = queue[front];
    	return 1;
    
    }

    队列还可以通过链表的存储方式来表示(链式存储):

    #include<stdio.h>
    #include<stdlib.h>
    
    typedef struct _queue_node
    {
    	int data;
    	struct _queue_node * next;
    }QUEUE;
    
    QUEUE * rear = NULL;
    QUEUE * front = NULL;
    
    int InQueue(int value)
    {
    	QUEUE * q = (QUEUE *)malloc(sizeof(QUEUE));
    	if(q == NULL) return 0;
    	q->data = value;
    	q->next = NULL;
    	if(front == NULL)
    		front = q;
    	else
    		rear->next = q;
    	rear = q;
    	return 1;
    }
    
    int OutQueue(int *value)
    {
    	QUEUE * p = NULL;
    	if(front == NULL)
    		return 0;
    	p = front;
    	front = front->next;
    	*value = p->data;
    	free(p);
    	return 1;
    }
  • 相关阅读:
    网页设计~老生常谈~浏览器兼容2个主要问题的解决
    谈谈网页功能测试
    从PMP学习中浅谈公司行政工作
    肉肉谈对需求设计的想法到底是功能驱动界面?还是界面驱动功能?
    jndi和rmi学习
    mysql赋值变量:=的使用
    用Cookies和HashTable制作购物车
    nginx实现简单的反向代理
    .net Form认证扩展保存 Object 类型
    基于Docker搭建私有镜像仓库
  • 原文地址:https://www.cnblogs.com/shenerguang/p/2332435.html
Copyright © 2020-2023  润新知