队列(数据结构)

队列,一种特殊的线性表

它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

特点:只允许在一端输入,在另一端输出。输入端称为队尾,输出端称为队头

因此,队列,又称为先进先出表,类似于生活中的排队,先来的排在前头,后来的排在后头,一个一个办理业务。

队列有两种,一种叫做循环队列,另一种叫做链式队列。

 特点:先进先出

一.链式队列

1.结构体的定义

typedef struct LinkNode{
 	int data;
 	LinkNode* next;
 }*LinkNodePtr;
 
 /**
  *链列队.
  */
  typedef struct LinkQueue{
  	LinkNodePtr front;
  	LinkNodePtr rear;
  }*LinkQueuePtr;

2.初始化

创建一个链队列。

LinkQueuePtr initQueue(){
   	LinkQueuePtr resultPtr;
   	printf("In iniQueue, the address of resultPtr is %d\r\n",&resultPtr);
   	 resultPtr = (LinkQueuePtr)malloc(sizeof(LinkQueue));
   	 printf("The value of resultPtr is %d\r\n",&resultPtr);
   	//The header, the data is not useful.
   	LinkNodePtr headerPtr;
   	 printf("The address of headerPtr is %d\r\n",&headerPtr);
   	 headerPtr = (LinkNodePtr)malloc(sizeof(LinkNodePtr));
   	 printf("The value of headerPtr is %d\r\n",headerPtr);
   	headerPtr->next = NULL;
	   
	resultPtr->front = headerPtr;
	resultPtr->rear = headerPtr;
	return resultPtr; 
   }// Of initQueue

3.输出链队列里面的数据元素

void outputLinkQueue(LinkQueuePtr paraQueuePtr){
    	LinkNodePtr tempPtr;
    	printf("In paintLinkQueue, the address of tempPtr is %d\r\n",&tempPtr);
    	tempPtr = paraQueuePtr->front->next;
    	printf("The value of tempPtr is %d\r\n",tempPtr);
    	printf("This is a queue: ");
    	while(tempPtr != NULL){
    		printf("%d ",tempPtr->data);
    		tempPtr = tempPtr->next;
		} //Of while
		printf("\r\n");
	}// Of outputLinkQueue

 

4.数据入队

链式队列数据入队
链队队列中,当有新的数据元素入队,只需进行以下 3 步操作:

将该数据元素用节点包裹,例如新节点名称为 elem;
与 rear 指针指向的节点建立逻辑关系,即执行 rear->next=elem;
最后移动 rear 指针指向该新节点,即 rear=elem;

void enqueue(LinkQueuePtr paraQueuePtr, int paraElement){
	 	//step 1.Creat a new node.
	 	LinkNodePtr tempNodePtr;
	 	printf("In linkEnqueue, the address of tempNodePtr is %d\r\n",&tempNodePtr);
	 	
	 	tempNodePtr = (LinkNodePtr)malloc(sizeof(LinkNodePtr));
	 	printf("The value of tempNodePtr is %d\r\n",tempNodePtr);
	 	tempNodePtr->data = paraElement;
	 	tempNodePtr->next = NULL;
	 	
	 	//step 2. Link to the existing rear
	 	paraQueuePtr->rear->next = tempNodePtr;
	 	
	 	//step 3. It is the rear
	 	paraQueuePtr->rear = tempNodePtr;
	 }// Of enqueue

4.出队列

int dequeue(LinkQueuePtr paraQueuePtr){
	  	int resultValue;
	  	LinkNodePtr tempNodePtr;
	  	
	  	// Step 1. Is the queue empty?
	  	printf("dequeue test 1\r\n");
	  	if(paraQueuePtr->front == paraQueuePtr->rear){
	  		printf("The queue is empty.\r\n");
	  		return -1;
		  }// of if
		  
		  // step 2.Change the queue.
		  printf("dequeue test 2\r\n");
		  tempNodePtr = paraQueuePtr->front->next;
		  resultValue = tempNodePtr->data;
		  paraQueuePtr->front->next = paraQueuePtr->front->next->next;
		  
		  if(paraQueuePtr->rear == tempNodePtr){
		  	 paraQueuePtr->rear = paraQueuePtr->front;
		  }// Of if
		  
		  printf("dequeue test 3, the ptr is %d\r\n",tempNodePtr);
		  // step 3. Free space.
		  //free(tempNodePtr)
		  
		  // step 4.Return.
		  printf("trying to dequeue %d\r\n",resultValue);
		  return resultValue;
	  }// Of enqueue
	  

5.测试函数

void testLinkQueue(){
	   	printf("Start testing.");
	   	LinkQueuePtr tempQueuePtr;
	   	tempQueuePtr = initQueue();
	   	enqueue(tempQueuePtr,10);
	   	enqueue(tempQueuePtr,30);
	   	enqueue(tempQueuePtr,50);
	   	
	   	printf("Before outputLinkQueue.\r\n");
	   	outputLinkQueue(tempQueuePtr);
	   	printf("After outputLinkQueue.\r\n");
	   	
	   	printf("dequeue gets %d",dequeue(tempQueuePtr));
	   	printf("dequeue gets %d",dequeue(tempQueuePtr));
	   	printf("dequeue gets %d",dequeue(tempQueuePtr));
	   	printf("dequeue gets %d",dequeue(tempQueuePtr));
	   }// Of testLinkQueue
	   

6.运行结果

The value of headerPtr is 11473936
In linkEnqueue, the address of tempNodePtr is 6487464
The value of tempNodePtr is 11473968
In linkEnqueue, the address of tempNodePtr is 6487464
The value of tempNodePtr is 11474000
In linkEnqueue, the address of tempNodePtr is 6487464
The value of tempNodePtr is 11474032
Before outputLinkQueue.
In paintLinkQueue, the address of tempPtr is 6487464
The value of tempPtr is 11473968
This is a queue: 10 30 50
After outputLinkQueue.
dequeue test 1
dequeue test 2
dequeue test 3, the ptr is 11473968
trying to dequeue 10
dequeue gets 10dequeue test 1
dequeue test 2
dequeue test 3, the ptr is 11474000
trying to dequeue 30
dequeue gets 30dequeue test 1
dequeue test 2
dequeue test 3, the ptr is 11474032
trying to dequeue 50
dequeue gets 50dequeue test 1
The queue is empty.
dequeue gets -1

二、循环队列

队满状态:q.rear==q.front

队满状态:(q.rear + 1 )%MAX_SPACE==q.front

1.定义结构体

typedef struct CircleIntQueue{
	int data[TOTAL_SPACE];
	
	int head;
	
	int tail;
}*CircleIntQueuePtr;

2.列队初始化

CircleIntQueuePtr initQueue(){
	CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
	resultPtr->head = 0;
	resultPtr->tail = 0;
	
	return resultPtr;
}

3.入队

void enqueue(CircleIntQueuePtr paraPtr,int paraValue){
	if((paraPtr->tail+1)%TOTAL_SPACE == paraPtr->head){
		printf("Queue full.\r\n");
		return;
	}
	
	paraPtr->data[paraPtr->tail%TOTAL_SPACE] = paraValue;
	paraPtr->tail++;
}

4.出队

int dequeue(CircleIntQueuePtr paraPtr){
	int resultValue;
	if(paraPtr->head == paraPtr->tail){
		printf("no element in the queue.\r\n");
		return -1;
	}
	resultValue = paraPtr->data[paraPtr->head%TOTAL_SPACE];
	paraPtr->head++;
	
	return resultValue;
}//of dequeue
 

5.输出队列里的元素数据

void outputLinkQueue(CircleIntQueuePtr paraPtr){
	int i;
	if(paraPtr->head == paraPtr->tail){
		printf("empty queue.");
		return; 
	}//of it
	
	printf("element in the queue:");
	for(i=paraPtr->head;i<paraPtr->tail;i++){
		printf("%d",paraPtr->data[i%TOTAL_SPACE]);
	}//of for it
	
	printf("\r\n");
}//of outputlinkquue

6.完整代码

#include<stdio.h>
#include<malloc.h>
 
#define TOTAL_SPACE 5
 
/*
*circle int queue
*/
typedef struct CircleIntQueue{
	int data[TOTAL_SPACE];
	
	int head;
	
	int tail;
}*CircleIntQueuePtr;
 
CircleIntQueuePtr initQueue(){
	CircleIntQueuePtr resultPtr = (CircleIntQueuePtr)malloc(sizeof(struct CircleIntQueue));
	resultPtr->head = 0;
	resultPtr->tail = 0;
	
	return resultPtr;
}
 
 void enqueue(CircleIntQueuePtr paraPtr,int paraValue){
	if((paraPtr->tail+1)%TOTAL_SPACE == paraPtr->head){
		printf("Queue full.\r\n");
		return;
	}
	
	paraPtr->data[paraPtr->tail%TOTAL_SPACE] = paraValue;
	paraPtr->tail++;
}
 
 int dequeue(CircleIntQueuePtr paraPtr){
	int resultValue;
	if(paraPtr->head == paraPtr->tail){
		printf("no element in the queue.\r\n");
		return -1;
	}
	resultValue = paraPtr->data[paraPtr->head%TOTAL_SPACE];
	paraPtr->head++;
	
	return resultValue;
}//of dequeue
 
/*
*output the queue
*/
 
void outputLinkQueue(CircleIntQueuePtr paraPtr){
	int i;
	if(paraPtr->head == paraPtr->tail){
		printf("empty queue.");
		return; 
	}//of it
	
	printf("element in the queue:");
	for(i=paraPtr->head;i<paraPtr->tail;i++){
		printf("%d",paraPtr->data[i%TOTAL_SPACE]);
	}//of for it
	
	printf("\r\n");
}//of outputlinkquue
 
void testLinkQueue(){
	int i=10;
	CircleIntQueuePtr tempPtr = initQueue();
	for(;i<16;i++){
		enqueue(tempPtr,i);
	}//of for it
	
   	outputLinkQueue(tempPtr);
	for(i=0;i<6;i++){
		printf("dequeue gets %d\r\n",dequeue(tempPtr));
	}//of for it
	
	enqueue(tempPtr,8);
	outputLinkQueue(tempPtr);
}
 
int main(){
	testLinkQueue();
	return 1;
}//of mian

7.运行结果

Queue full.
Queue full.
element in the queue:10111213
dequeue gets 10
dequeue gets 11
dequeue gets 12
dequeue gets 13
no element in the queue.
dequeue gets -1
no element in the queue.
dequeue gets -1
element in the queue:8

三、总结
队列就是只允许在一端进行插入,在另一端进行删除的线性表
队头(Front):允许删除的一端(队首)
队尾(Rear):允许插入的一端
其中,首尾相连的顺序存储的队列叫循环队列
入队:rear=(rear+1)%MaxSize
出队:front=(front+1)%MaxSize
队空:front=rear
队满:数组中仍有一个空余单元


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值