【データ構造学習記録8】-キュー

1.コンセプト

スタックとは異なり、キューは先进先出(first in first out = FIFO)構造です。FIFOはマイクロコントローラーのFIFOですか?これは、テーブルの一方の端に要素を挿入し、もう一方の端に要素を削除することのみを許可する線形テーブルです。キューでは、挿入できる端をと呼び队尾、削除できるをと呼び队头ます。

2.原則の実現

1.ノード

キューはまだ線形テーブルであるため、キューのノードは2つの部分で構成されている必要があります:数据区指向下一个节点的指针
ここに画像の説明を挿入

2.キュー

キューを実装する場合は、2つのポインターとそれを指すだけで済み队头和队尾ます。
チェーンストレージを使用するのが最善です。チェーンストレージ队头は頻繁に変更されるため、シーケンシャル構造を採用すると、スペースを浪費したり、多数の要素を頻繁に変更したりする可能性があります。
初期化時に、队头队尾すべて同じノードを指すことができ、ノードが指す次のノードはNULLです。
ここに画像の説明を挿入

3.チームに参加する

エンキューの場合、チームの終了後に要素を挿入し、チームの終了をその要素にポイントするだけで済みます。
ここに画像の説明を挿入

4.チームから抜け出します

チームのヘッドが指す次のノードのアドレスを保存し、それをアドレスAとして記録し、チームのヘッドをアドレスAの次のノードにポイントしてから、Aをfreeドロップします。
ここに画像の説明を挿入

5.破壊する

キューを破棄し、チームから最初からやり直してから、すべてのノードをfreeオフにします

3.コード

#include <stdio.h>
#include <stdlib.h>

#define OK      1
#define ERROR   0

typedef struct dataType{
    
    
    int data;
}dataType;

typedef struct nodeType{
    
    
    dataType data;
    struct nodeType *next;
}nodeType;

typedef struct queue{
    
    
    nodeType *head;
    nodeType *tail;
}queue;

queue* QueueInit(void);
int QueuePush(queue* q, dataType data);
int QueueGet(queue* q, dataType *datain);
int QueuePop(queue* q);
int QueueDistroy(queue *q);

int main()
{
    
    
    // 主函数内容随便改
    queue *Q = QueueInit();
    dataType test;
    int i = 0;
    for (i = 0; i < 5; ++i)
    {
    
    
        test.data = i;
        QueuePush(Q, test);
    }
    while(Q->head != Q->tail)
    {
    
    
        QueueGet(Q, &test);
        printf("%d\n", test.data);
        QueuePop(Q);
    }
    for (i = 5; i >= 0; --i)
    {
    
    
        test.data = i;
        QueuePush(Q, test);
    }
    while(Q->head != Q->tail)
    {
    
    
        QueueGet(Q, &test);
        printf("%d\n", test.data);
        QueuePop(Q);
    }
    return 0;
}

queue* QueueInit(void)
{
    
    
    queue* q = (queue*)malloc(sizeof(queue));
    nodeType* qhead = (nodeType*)malloc(sizeof(nodeType));
    // 动态生成一个队列和它里面的一个节点

    if (q != NULL && qhead != NULL)
    {
    
    
        qhead->next = NULL;
        qhead->data.data = -1;   //信息初始化
        q->head = qhead;    // 头尾都指向同一个节点
        q->tail = qhead;
        return q;
    }
    exit(0);
}

int QueuePush(queue* q, dataType datain)
{
    
    
    nodeType *node = (nodeType*)malloc(sizeof(nodeType));

    if (node != NULL)
    {
    
    
        node->data = datain;    // 更新节点数据
        node->next = NULL;
        q->tail->next = node;   // 更新队列
        q->tail = node;         // 跟新队尾指针
        return OK;
    }
    return ERROR;
}

int QueueGet(queue* q, dataType *datain)
{
    
    
    if (q->head != q->tail && q->head->next != NULL)
    {
    
    
        *datain = q->head->next->data;  // 获得头指针指向的节点
        return OK;
    }
    return ERROR;
}

int QueuePop(queue *q)
{
    
    
    nodeType *dnode = NULL;

    if(q->head != q->tail && q->head->next != NULL)
    {
    
    
        dnode = q->head;
        q->head = q->head->next;    // 将头指针指向现在头指针的下一个节点
        free(dnode);    // 释放空间
        return OK;
    }
    return ERROR;
}

int QueueDistroy(queue* q)
{
    
    
    nodeType *dnode = NULL;
    while(q->head != q->tail)   // 只要头不等于尾,队列就还有成员
    {
    
    
        dnode = q->head;
        q->head = q->head->next;
        free(dnode);    // 同理参考Pop
        return OK;
    }
    return ERROR;
}

おすすめ

転載: blog.csdn.net/u011017694/article/details/109446565