一、队列的定义
队列是一种先进先出的线性表,只允许在表的一端进行插入,而在另一端删除元素。这和我们日常中的排队时一致的,最早进入队列的元素最早离开。
二、链队列的结构
用链表表示的队列简称链队列。一个链队列显然需要头指针和尾指针才能唯一确定。
三、代码描述
1、队列结点及链队列
//链队列结点
typedef struct LinkNode
{
int data;
struct LinkNode* next;
}*LinkNodePtr;
//链队列
typedef struct LinkQueue
{
LinkNodePtr front;
LinkNodePtr rear;
}*LinkQueuePtr,LinkQueue;
2、初始化
//初始化
LinkQueuePtr iniQueue()
{
LinkQueuePtr resultPtr = (LinkQueuePtr)malloc(sizeof(LinkQueue));
LinkQueuePtr headerPtr = (LinkQueuePtr)malloc(sizeof(LinkQueue));
header->data = -1;
headerPtr->next = NULL;
resultPtr->front = headerPtr;
resultPtr->rear = headerPtr;
return resultPtr;
}
3、打印
void outputLinkQueue(LinkQueuePt paraQueuePtr)
{
LinkNodePtr tempPtr = paraQueuePtr->front->next;
while(tempPtr!=NULL)
{
printf("%d ",tempPtr->data);
tempPtr = tempPtr->next;
}
printf("\r\n");
}
4、入队
void enqueue(LinkQueuePtr paraQueuePtr,int paraElement)
{
LinkNodePtr tempNodePtr = (LinkNodePtr)malloc(sizeof(LinkNodePtr));
tempNodePtr->data = paraElement;
tempNodePtr->next = NULL;
paraQueuePtr->rear->next = tempNodePtr;
paraQueuePtr->rear = tempNodePtr;
}
5、出队
int dequeue(LinkQueuePtr paraQueue)
{
int resultValue;
LinkNodePtr tempNodePtr;
//队列是否为空
if(paraQueuePtr->front == paraQueuePtr->rear)
{
printf("The queue is empty.\r\n");
return -1;
}
//改变队列
tempNodePtr = paraQueuePtr->front->next;
resultValue = tempNodePtr->data;
paraQueuePtr->front->next = paraQueuePtr->front->next->next;
if(paraQueue->rear == tempNodePtr)
{
paraQueuePtr->rear = paraQueue->front;
}
//释放空间
tempNodePtr = NULL;
return resultValue;
}
6、测试
void testLinkQueue(){
LinkQueuePtr tempQueuePtr;
tempQueuePtr = initQueue();
enqueue(tempQueuePtr, 20);
enqueue(tempQueuePtr, 70);
enqueue(tempQueuePtr, 100);
outputLinkQueue(tempQueuePtr);
printf("dequeue gets %d\r\n",dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
printf("dequeue gets %d\r\n", dequeue(tempQueuePtr));
enqueue(tempQueuePtr, 6);
outputLinkQueue(tempQueuePtr);
}
20 70 100
dequeue gets 20
dequeue gets 70
dequeue gets 100
The queue is empty.
dequeue gets -1
6
四、循环队列
用一堆数组的形式来表示循环队列。在存储元素的时候通常是少用一个元素的空间,即队列空间大小为m时,有m-1个元素就队满。当头尾指针的值相等时则队列为空。而当尾指针在循环意义上加1后等于头指针时表示队满,因此在循环队列中队空队满的判断条件是:
队空条件:Q.fornt = Q.rear;
队满的条件:(Q.rear+1) % MAX_SIZE = Q.front;
不同的队首和队尾的初始化,将导致我们判断队列是否已满以及队列是否为空的方法的不同。
(1)front和rear初始化均为0。那么,front会永远指向队首元素,而rear会指向队尾元素的下一格。
(2)front和rear错开。比如 front 初始为0,rear初始为5。在这种情况下front会永远指向队首元素,rear会永远指向队尾元素。因此,在判断队列是否已满与非空时,初始化不同,判断方式不同。或者干脆就不用front与rear的位置来判断队列是否已满与非空。多加一个参数Size,表示队列的现有容积也行。
满了之后到a1,front到了a6应该表示队空,但循环又回到起点
代码实现
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 outputLinkQueue(CircleIntQueuePtr paraPtr)
{
int i;
if (paraPtr->head == paraPtr->tail)
{
printf("队列空.");
return;
}
printf("队列: ");
for (i = paraPtr->head; i < paraPtr->tail; i++)
{
printf("%d, ", paraPtr->data[i % TOTAL_SPACE]);
}
printf("\r\n");
}
4.入队
void enqueue(CircleIntQueuePtr paraPtr, int paraValue)
{
if ((paraPtr->tail + 1) % TOTAL_SPACE == paraPtr->head) {
printf("队列已满.\r\n");
return;
}
paraPtr->data[paraPtr->tail % TOTAL_SPACE] = paraValue;
paraPtr->tail++;
}
5.出队
int dequeue(CircleIntQueuePtr paraPtr)
{
int resultValue;
if (paraPtr->head == paraPtr->tail)
{
printf("队列为空不可删除.\r\n");
return -1;
}
resultValue = paraPtr->data[paraPtr->head % TOTAL_SPACE];
paraPtr->head++;
return resultValue;
}
测试
void testLinkQueue()
{
int i = 9;
CircleIntQueuePtr tempPtr = initQueue();
for (; i < 15; i ++)
{
enqueue(tempPtr, i);
}
outputLinkQueue(tempPtr);
for (i = 0; i < 6; i ++)
{
printf("dequeue gets %d\r\n", dequeue(tempPtr));
}
outputLinkQueue(tempPtr);
for (i = 0; i < 2; i ++)
{
printf("dequeue gets %d\r\n", dequeue(tempPtr));
}
enqueue(tempPtr, 8);
outputLinkQueue(tempPtr);
}
队列已满.
队列已满.
队列: 9, 10, 11, 12,
dequeue gets 9
dequeue gets 10
dequeue gets 11
dequeue gets 12
队列为空不可删除.
dequeue gets -1
队列为空不可删除.
dequeue gets -1
队列空.队列为空不可删除.
dequeue gets -1
队列为空不可删除.
dequeue gets -1
队列: 8,