由于工作需求, 需要开发一个C版本的队列, 经过一天的开发测试, 原始版本已完成;
这也是我个人的第一篇博客, 希望将来能帮助更多后来开发者;
废话不多说, 直接进入主题。
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,
和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素成为出队。
因为队列只允许在一段插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,
故队列又称为先进先出(FIFO—first in first out)线性表;
以上红字部分是借鉴于百度百科: 队列
关于实现:
队列的链式存储结构简称为链队列。它是限制仅在表头删除和表尾插入的单链表, 如下图:
如图所示, 我们会创建两个指针,front表示头指针, rear表示尾指针;
和线性表的单链表一样,为了操作方便,我们也给链队列添加一个头结点,并令头指针指向头结点;
链队列为空时, 头指针和尾指针均指向头结点;
这次主要是实现了几个功能:
init -->创建
insert-->插入
remove-->删除
deIninit-->销毁
插入讲解:
删除讲解:
以下是代码部分:
/*
beginning of the queue -- remove element
end tail of the queue -- insert element
*/
#include<stdio.h>
#include<stdlib.h>
#define true 1
#define false 0
typedef int QElemCommonType;
typedef int Status;
typedef struct historyQueueNode
{
QElemCommonType data;
struct historyQueueNode *next;
}SHistoryQueueNode,*pSHistoryQueueNode;
// this struct maintains a queue beginning pointer and end pointer
// the pointer will point to the node of queue.
typedef struct linkQueue
{
pSHistoryQueueNode front; // queue beginning pointer
pSHistoryQueueNode rear; // queue end pointer
}SLinkQueue;
// method protype
int initHistoryQueue(SLinkQueue *historyQueue);
int deInitHistoryQueue(SLinkQueue *historyQueue);
int clearHistoryQueue(SLinkQueue *historyQueue);
int insertHistoryQueue(SLinkQueue *historyQueue, QElemCommonType data);
int removeHistoryQueue(SLinkQueue *historyQueue, QElemCommonType *data);
int printHistoryQueue(SLinkQueue *historyQueue);
int initHistoryQueue(SLinkQueue *historyQueue)
{
int result = false;
do
{
// create a empty queue, the beginning and end queue will point to the head node.
historyQueue-> front = historyQueue-> rear = (struct historyQueueNode *)malloc(sizeof(struct historyQueueNode));
if(!historyQueue->front)
{
result = false;
break;
}
historyQueue->front->next = NULL;
//set return result to true;
result = true;
}while(0);
return result;
}
// destory the queue, the queue is not exist;
// from the beginning of queue, destory each node;
// remove the head node, then the first, second node, untill remove it to end.
int deInitHistoryQueue(SLinkQueue *historyQueue)
{
/*
q->front will point to head node,
q->front->next will point to the fisrt node.
*/
while(historyQueue->front)
{
historyQueue->rear = historyQueue->front->next;
free(historyQueue->front);
historyQueue->front = historyQueue->rear;
}
return true;
}
int insertHistoryQueue(SLinkQueue *historyQueue, QElemCommonType data)
{
int result = false;
// insert element e
pSHistoryQueueNode newNode = (struct historyQueueNode *)malloc(sizeof(struct historyQueueNode));
if(!newNode)
{
result = false;
}
//set data to new node
newNode->data = data;
newNode->next = NULL;
//add the new data into link queue
historyQueue->rear->next = newNode;
historyQueue->rear = newNode;
result = true;
return result;
}
int removeHistoryQueue(SLinkQueue *historyQueue, QElemCommonType *data)
{
int result = false;
do
{
//if queue is not empty, remove head element
if(historyQueue->front == historyQueue->rear)
{
result = false;
break;
}
// get and remove the oldest node from the link queue.
pSHistoryQueueNode oldNode = historyQueue->front->next; //the head element
historyQueue->front->next = oldNode->next;
*data = oldNode->data;
//if the element which will be removed is end element, the queue is empty.
if(historyQueue->rear == oldNode)
{
historyQueue->rear = historyQueue->front;
}
//free
free(oldNode);
result = true;
}while(0);
return result;
}
int printHistoryQueue(SLinkQueue *historyQueue)
{
if(historyQueue->front==NULL)
{
printf("queue is not exist\n");
}
else if(historyQueue->front==historyQueue->rear)
{
printf("queue is empty\n");
}
else
{
//traverse link list queue.
SHistoryQueueNode *temp;
temp = historyQueue->front->next;
while (temp)
{
printf("%d ",temp->data);
temp = temp->next;
}
printf("\n");
}
return true;
}
int main()
{
SLinkQueue q;
int i,n;
QElemCommonType e;
printf("main: ====initHistoryQueue start====\n");
initHistoryQueue(&q);
printf("main: ====initHistoryQueue end====\n");
printf("main: please input insert number n: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
insertHistoryQueue(&q,i);
}
printf("main: printHistoryQueue: \n");
printHistoryQueue(&q);
printf("main: removeHistoryQueue: \n");
printf("main: please input remove number n: ");
scanf("%d",&n);
printf("main: remove number is ");
for(i = 0; i < n; i++)
{
removeHistoryQueue(&q, &e);
printf("%d ", e);
}
printf("\n");
printf("main: printHistoryQueue: \n");
printHistoryQueue(&q);
printf("main: deInitHistoryQueue \n");
deInitHistoryQueue(&q);
printf("main: printHistoryQueue once again.\n");
printHistoryQueue(&q);
return 0;
}
测试结构如下:
duser@136.17.78.38:~/Desktop/testFunction/Queue$ gcc v2x_queue.c -o test
duser@136.17.78.38:~/Desktop/testFunction/Queue$ ./test
main: ====initHistoryQueue start====
main: ====initHistoryQueue end====
main: please input insert number n: 100
main: printHistoryQueue:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
main: removeHistoryQueue:
main: please input remove number n: 50
main: remove number is 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
main: printHistoryQueue:
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
main: deInitHistoryQueue
main: printHistoryQueue once again.
queue is not exist
duser@136.17.78.38:~/Desktop/testFunction/Queue$
最后希望看的时候动起手来,画画图会更加容易理解;
代码中希望尽可能完善它; 另外请把int返回类型改成bool;
Best wishes!
Yannick Tong.