C語言數據結構、第三節課----隊列(鏈式存儲)

一、概念:

隊列是一種特殊的線性表,盡在兩端進行操作,隊頭:取出數據元素的一端;隊尾:插入數據元素的一端,隊列是不允許在中間部位進行操作的,所以隊列是先進先出,(first in first out  FIFO ) 允許插入的一端是隊尾,允許刪除的一端是隊頭。如圖所示: 

  

上面就是隊列的邏輯示意圖,所以我們可以通過線性表的鏈式存儲來模仿隊列的鏈式存儲。

二、隊列的API函數:

1.隊列的常用操作:

  1. 銷燬隊列
  2. 清空隊列
  3. 進隊列
  4. 出隊列
  5. 獲取隊頭元素
  6. 獲取隊列的長度

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.整個代碼是線性表來模仿隊列,所以更能證明,其實隊列就是一種特殊的線性表。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章