一、概念:
隊列是一種特殊的線性表,盡在兩端進行操作,隊頭:取出數據元素的一端;隊尾:插入數據元素的一端,隊列是不允許在中間部位進行操作的,所以隊列是先進先出,(first in first out FIFO ) 允許插入的一端是隊尾,允許刪除的一端是隊頭。如圖所示:
上面就是隊列的邏輯示意圖,所以我們可以通過線性表的鏈式存儲來模仿隊列的鏈式存儲。
二、隊列的API函數:
1.隊列的常用操作:
- 銷燬隊列
- 清空隊列
- 進隊列
- 出隊列
- 獲取隊頭元素
- 獲取隊列的長度
2.我們首先需要創建一個隊列的業務邏輯結構體:
因爲隊列是特殊的線性表,所以我們寫隊列的鏈式存儲的代碼時候,我們利用了前面學習的線性錶鏈式存儲的代碼:
1>queue.h
#ifndef __QUEUE__
#define __QUEUE__
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"seqlist.h"
typedef void queue;
queue * queue_create();
void queue_destroy(queue *q);
void queue_clear(queue *q);
int queue_append(queue *q,void *item);
void *queue_retrieve(queue *q);
void * queue_header(queue *q);
int queue_length(queue *q);
#endif
2>queue.c
#include"queue.h"
typedef struct _queue_node
{
list_node node;
void *item;
}queue_node;
queue * queue_create()
{
int ret = 0;
queue * tmp = NULL;
tmp = seqlist_create();
if (NULL == tmp)
{
ret = -1;
printf("queue_create error :%d \n",ret);
return NULL;
}
return tmp;
}
void queue_destroy(queue *q)
{
seqlist_destroy(q);
return;
}
void queue_clear(queue *q)
{
seqlist_clear(q);
return ;
}
int queue_append(queue *q,void *item)
{
int ret= 0;
queue_node *tmp = NULL;
tmp = (queue_node *)malloc(sizeof(queue_node));
if(NULL == tmp)
{
ret = -1;
printf("queue_append malloc error :%d \n",ret);
return ret;
}
memset(tmp,0,sizeof(queue_node));
tmp->item = item;
ret = seqlist_insert(q,(list_node *)tmp,seqlist_length(q));
if(ret != 0)
{
ret = -2;
printf("queue_append malloc error :%d \n",ret);
return ret;
}
return 0;
}
//出隊列,從線性表中刪除0號位置元素
void *queue_retrieve(queue *q)
{
int ret = 0;
queue_node *tmp = NULL;
void *tmp1 = NULL;
tmp = (queue_node *)seqlist_delete(q,0);
if(NULL == tmp)
{
ret =-1;
printf("queue_retrieve error :%d \n",ret);
return NULL;
}
tmp1 = tmp->item;
if(tmp != NULL)
{
free(tmp);
}
return tmp1;
}
void* queue_header(queue *q)
{
int ret = 0;
queue_node *tmp = NULL;
void * tmp1 = NULL;
tmp = (queue_node *)seqlist_get(q,0);
if(NULL == tmp)
{
ret = -1;
printf("queue_header error :%d \n",ret);
return NULL;
}
return tmp->item;
}
int queue_length(queue *q)
{
return seqlist_length(q);
}
3>main.c(測試代碼)
#include<stdio.h>
#include"queue.h"
int main(int argc,char* argv[])
{
queue *qu = queue_create();
int i = 0;
int arr[10] = {0};
for(i = 0;i < 10;i++)
{
arr[i] = i+10;
}
for(i = 0; i <10;i++)
{
queue_append(qu,&arr[i]);
}
int length = queue_length(qu);
printf("隊列的長度爲:%D \n",length);
int head = *((int *)queue_header(qu));
printf("隊首的位置爲:%d \n",*((int *)queue_header(qu)));
printf("一個一個清空隊列 \n");
for(i =0;i < 10;i++)
{
printf("插入的順序元素爲:%d",*((int *)queue_retrieve(qu)));
}
printf(" \n");
return 0;
}
總結:
1.
typedef struct _queue_node
{
list_node node;
void *item;
}queue_node;
在隊列中,這個隊列節點,和棧節點一樣,這是用來定義一箇中間變量的,因爲我們傳進來的是一個業務節點,而我們的隊列用的是線性表來模仿的,所以,業務節點無法插進去隊列,所以這個時候我們需要的是一箇中間變量,充當線性表的節點,還可以同時將業務節點數據保存進線性表,所以我們定義了一個這樣的中間數據類型;
2.整個代碼是線性表來模仿隊列,所以更能證明,其實隊列就是一種特殊的線性表。