zoukankan      html  css  js  c++  java
  • "队列"学习

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

    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;
    }
  • 相关阅读:
    [APM] OneAPM 云监控部署与试用体验
    Elastic Stack 安装
    xBIM 综合使用案例与 ASP.NET MVC 集成(一)
    JQuery DataTables Selected Row
    力导向图Demo
    WPF ViewModelLocator
    Syncfusion SfDataGrid 导出Excel
    HTML Table to Json
    .net core 2.0 虚拟目录下载 Android Apk 等文件
    在BootStrap的modal中使用Select2
  • 原文地址:https://www.cnblogs.com/shenerguang/p/2332435.html
Copyright © 2011-2022 走看看