日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux C 数据结构——队列

發布時間:2023/12/9 linux 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux C 数据结构——队列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? 還是先放這張圖,以便對比和理解:

?

?? 隊列是限制在兩端進行插入操作和刪除操作的線性表,允許進行存入操作的一端稱為“隊尾”,允許進行刪除操作的一端稱為“隊頭”。當線性表中沒有元素時,稱為“空隊”。特點:先進先出(FIFO)。

一、順序隊列 ???????建立順序隊列結構必須為其靜態分配或動態申請一片連續的存儲空間,并設置兩個指針進行管理。一個是隊頭指針front,它指向隊頭元素;另一個是隊尾指針rear,它指向下一個入隊元素的存儲位置,如圖所示

???? 每次在隊尾插入一個元素是,rear增1;每次哎隊頭刪除一個元素時,front增1。隨著插入和刪除操作的進行,隊列元素的個數不斷變化,隊列所占的存儲空間也在為隊列結構所分配的連續空間中移動。當front=rear時,隊列中沒有任何元素,稱為空隊列。當rear增加到指向分配的連續空間之外時,隊列無法再插入新元素,但這時往往還有大量可用空間未被占用,這些空間是已經出隊的隊列元素曾經占用過得存儲單元。

??? 在實際使用隊列時,為了使隊列空間能重復使用,往往對隊列的使用方法稍加改進:無論插入或刪除,一旦rear指針增1或front指針增1 時超出了所分配的隊列空間,就讓它指向這片連續空間的起始位置。自己真從N(MaxSize)增1變到0,可用取余運算rear%N和front%N來實現。這實際上是把隊列空間想象成一個環形空間,環形空間中的存儲單元循環使用,用這種方法管理的隊列也就稱為循環隊列

??? 在循環隊列中,當隊列為空時,有front=rear,而當所有隊列空間全占滿時,也有front=rear。為了區別這兩種情況,規定循環隊列最多只能有MaxSize-1個隊列元素,當循環隊列中只剩下一個空存儲單元時,隊列就已經滿了。因此,隊列判空的條件時front=rear,而隊列判滿的條件時front=(rear+1)%MaxSize。

總結:

1、隊頭指針front,指向隊頭元素的位置的前一個位置。即指向預留的位置;

2、隊尾指針rear,指向隊尾元素的位置;

3、入隊: rear = (rear + 1) % N (maxsize),然后元素放入隊尾rear所指向的位置;

4、出隊: front = (front + 1) % N,然后取出隊頭指針front所指向的元素;

5、隊空: front == rear;

6、隊滿: (rear + 1) % N == front, N為數組的元素個數;

7、為了區別空隊和滿隊,滿隊元素個數比數組元素個數少一個。

下面是順序隊列的運算:

?? 順序隊列也是順序表的一種,具有順序表同樣的存儲結構,由數組定義,配合使用數組下表表示的隊頭指針和隊尾完成各種操作:

[cpp]?view plaincopy
  • #define?N?64??//隊列中數據元素的數據類型??
  • typedef?int?data_t;??
  • typedef?struct??
  • {??
  • ????data_t?data[N];?//用數組作為隊列的儲存空間??
  • ????int?front,rear;?//指示隊頭位置和隊尾位置的指針??
  • }sequeue_t;??
  • 1、創建空隊列

    [cpp]?view plaincopy
  • sequeue_t?*CreateEmptySequeue()??
  • {??
  • ????sequeue_t?*queue;??
  • ????queue?=?(sequeue_t?*)malloc(sizeof(sequeue_t));??
  • ????if?(NULL?==?queue)?return?NULL;??
  • ??????
  • ????queue->front?=?queue->rear?=?0;??
  • ??
  • ????return?queue;??
  • }??
  • 2、摧毀一個隊列

    [cpp]?view plaincopy
  • void?DestroySequeue(sequeue_t?*queue)??
  • {??
  • ????if?(NULL?!=?queue)???
  • ????{??
  • ????????free(queue);??
  • ????}??
  • }??
  • 3、判斷一個隊列是否為空

    [cpp]?view plaincopy
  • int?EmptySequeue(sequeue_t?*queue)??
  • {??
  • ????if?(NULL?==?queue)???
  • ????????return?-1;??
  • ??
  • ????return?(queue->front?==?queue->rear???1?:?0);??
  • }??
  • 4、判斷一個隊列是否為滿

    [cpp]?view plaincopy
  • int?FullSequeue(sequeue_t?*queue)??
  • {??
  • ????if?(NULL?==?queue)?return?-1;??
  • ??
  • ????return?((queue->rear?+?1)?%?N?==?queue->front???1?:?0);??
  • }??
  • 5、清空一個隊列

    [cpp]?view plaincopy
  • void?ClearSequeue(sequeue_t?*queue)??
  • {??
  • ????if?(NULL?==?queue)?return;??
  • ??????
  • ????queue->front?=?queue->rear?=?0;??
  • ??
  • ????return;??
  • }??
  • 6、入隊

    [cpp]?view plaincopy
  • int?EnQueue(sequeue_t?*queue,?data_t?x)??
  • {??
  • ????if?(NULL?==?queue)?return?-?1;??
  • ??
  • ????if?(1?==?FullSequeue(queue))?return?-1;?/*?full?*/??
  • ??
  • ????queue->rear?=?(queue->rear?+?1)?%?N;??
  • ????queue->data[queue->rear]?=?x;??
  • ??
  • ????return?0;??
  • }??
  • 7、出隊

    [cpp]?view plaincopy
  • int?DeQueue(sequeue_t?*queue,?data_t?*x)??
  • {??
  • ????if?(NULL?==?queue)?return?-1;??
  • ??
  • ????if?(1?==?EmptySequeue(queue))?return?-1;?/*?empty?*/??
  • ??
  • ????queue->front?=?(queue->front?+?1)?%?N;??
  • ??
  • ????if?(NULL?!=?x)?{??
  • ????????*x?=?queue->data[queue->front];??
  • ????}??
  • ??
  • ????return?0;??
  • }??

  • 二、鏈式隊列

    ????? 用鏈表表示的隊列簡稱為鏈隊列,如下圖所示


    一個鏈隊列顯然需要兩個分別指示隊頭和隊尾的指針(分別成為頭指針和尾指針)才能唯一確定。這里,和線性表的單鏈表一樣,為了操作方便起見,我們也給隊列添加一個頭結點,并令頭指針指向頭節點。由此,空的鏈隊列的判決條件為頭指針和尾指針均指向頭結點,如下圖所示:

    ?

    鏈隊列的操作記為單鏈表的插入和刪除操作的特殊情況,插入操作在隊尾進行,刪除操作在隊頭進行,由隊頭指針和隊尾指針控制隊列的操作:

    [cpp]?view plaincopy
  • typedef?int?data_t;??
  • typedef?struct?node_t??
  • {??
  • ????data_t?data;??
  • ????struct?node_t?*next;??
  • }linknode_t,*linklist_t;??
  • typedef?struct??
  • {??
  • ????linklist_t?front,rear;??
  • }linkqueue_t;??
  • 1、創建空隊列

    [cpp]?view plaincopy
  • linkqueue_t?*CreateEmptyLinkqueue()??
  • {??
  • ????linkqueue_t?*lp?=?(linkqueue_t?*)malloc(sizeof(linkqueue_t));??
  • ????if(lp?==?NULL)??
  • ????????return;??
  • ??
  • ????lp->front?=?lp->rear?=?(linknode_t?*)malloc(sizeof(linknode_t));??
  • ????if(lp->front?==?NULL)??
  • ????????return;???
  • ??
  • ????lp->front->next?=?NULL;??
  • ??
  • ????return?lp;??
  • }??
  • 2、摧毀一個鏈隊列

    [cpp]?view plaincopy
  • void?DestroyLinkqueue(linkqueue_t?*queue)??
  • {??
  • ????if(queue?!=?NULL)??
  • ????{??
  • ????????ClearLinkqueue(queue);??
  • ????????free(queue);??
  • ????}??
  • }??
  • 3、清空一個鏈隊列

    [cpp]?view plaincopy
  • void?ClearLinkqueue(linkqueue_t?*queue)??
  • {??
  • ????linknode_t?*qnode;??
  • ??
  • ????while(q->front)??
  • ????{??
  • ????????qnode?=?queue->front;??
  • ????????queue->front=?qnode->next;??
  • ????????free(qnode);??
  • ????}??
  • ????queue->rear?=?NULL;}??
  • 4、判斷鏈隊列為空

    [cpp]?view plaincopy
  • int?EmptyLinkqueue(linkqueue_t?*queue)??
  • {??
  • ????if(queue?==?NULL)??
  • ????return?-1;??
  • ??????
  • ????return(queue->front?==?queue->rear???1?:?0);??
  • }??
  • 5、入隊

    [cpp]?view plaincopy
  • int?EnQueue(linkqueue_t?*queue,data_t?x)??
  • {??
  • ????linknode_t?*node_new;??
  • ????if(queue?==?NULL)??
  • ????????return?-1;??
  • ??
  • ????node_new?=?(linknode_t?*)malloc(sizeof(linknode_t));??
  • ????if(node_new?==?NULL)??
  • ????????return?-1;??
  • ??
  • ????node_new->data?=?x;??
  • ????node_new->next?=?NULL;??
  • ??
  • ????if(queue->front->next?==?NULL)??
  • ????{??
  • ????????queue->front->next?=?queue->rear?=?node_new;??
  • ????}??
  • ????else??
  • ????{??
  • ????????queue->rear->next?=?node_new;??
  • ????????queue->rear?=?node_new;??
  • ????}??
  • ????return?0;?????
  • }??
  • 6、出隊

    [cpp]?view plaincopy
  • int?DeQueue(linkqueue_t?*queue,data_t?*x)??
  • {??
  • ????linknode_t?*node_remove;??
  • ??
  • ????if(queue?==?NULL?||?queue->front->next?==?NULL)??
  • ????????return?-1;??
  • ??
  • ????node_remove?=?queue->front->next;??
  • ????queue->front->next?=?node_remove->next;??
  • ??
  • ????if(x?!=?NULL)??
  • ????????*x?=?node_remove->data;??
  • ??
  • ????free(node_remove);??
  • ??
  • ????return?0;??
  • }??
  • 總結

    以上是生活随笔為你收集整理的Linux C 数据结构——队列的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。