banner
cos

cos

愿热情永存,愿热爱不灭,愿生活无憾
github
tg_channel
bilibili

データ構造学習ノート<3> キュー

一、キューの抽象データ型の説明#

型名:キュー(Queue)
データオブジェクトの集合:0 個以上の要素を持つ有限線形リスト
操作の集合:長さが MaxSize のキュー Q∈Queue、キューの要素 item∈ElementType

1. 長さが MaxSize の空のキューを生成する
Queue CreatQueue(int MaxSize);
2. キュー Q が満杯かどうかを判断する
bool IsFullQ(Queue Q, int MaxSize);
3. データ要素 item をキュー Q に挿入する
bool AddQ(Queue Q, ElementType item);
4. キュー Q が空かどうかを判断する
bool IsEmptyQ(Queue Q);
5. キューの先頭要素を削除して返す
ElementType DeleteQ(Queue Q);

二、キューの順序保存実装#

1. 定義#

キューの順序保存構造は通常、1 次元配列キューの先頭要素の位置を記録する変数 frontキューの末尾要素の位置を記録する変数 rearから構成されます。
配列を移動して、環状になり、循環キューになります。
キューの空と満杯を判断するために、循環キューは n-1 個の配列スペースのみを使用します。
image
以下は定義のコードです

typedef struct QNode *Queue;
struct QNode {
    ElementType Data[MaxSize];//1次元配列
    int rear;//キューの末尾要素の位置を記録
    int front;//キューの先頭要素の位置を記録  
    int MaxSize;
    //実際にはfrontはキューの先頭要素のインデックスの前を指しています
};

2. 操作#

(1) 循環キューの作成(CreateQueue)#

Queue CreateQueue( int MaxSize ) {
    Queue Q = (Queue)malloc(sizeof(struct QNode));
    Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
    Q->front = Q->rear = 0;
    Q->MaxSize = MaxSize;
    return Q;
}

(2) キューが満杯かどうかを判断する(IsFull)#

bool IsFull( Queue PtrQ ) {//frontとrear+1の剰余が等しい場合、キューは満杯です
    return ((PtrQ->rear+1) % PtrQ->MaxSize == PtrQ->front);
}

(3) キューに要素を追加する(AddQ)#

キューが満杯かどうかを判断する必要があります

bool AddQ(Queue PtrQ, ElementType item) {
    if ( IsFull(PtrQ) ) {
        printf("キューは満杯です");//frontとrear+1の剰余が等しい場合、キューは満杯です
        return false;
    } else {
    	PtrQ->rear = (PtrQ->rear+1) % PtrQ->MaxSize; 
    	//キューの末尾rearを移動するために剰余演算を使用して循環を実現します
    	PtrQ->Data[PtrQ->rear] = item;
    	return true;
    }
}

(4) キューが空かどうかを判断する(IsEmpty)#

bool IsEmpty(Queue PtrQ) {
    return ( PtrQ->front == PtrQ->rear );
}

(5) キューから要素を削除する(DeleteQ)#

キューが空かどうかを判断してから削除します

ElementType DeleteQ(Queue PtrQ) {
    if(IsEmpty(PtrQ)) {//rearとfrontが等しい場合、キューは空です
        printf("キューは空です");
        return false;
    } else {
        PtrQ->front = (PtrQ->front+1) % PtrQ->MaxSize;//キューの先頭frontを移動する
        return PtrQ->Data[PtrQ->front];
    }
}

三、キューの連結保存実装#

1. 定義#

キューの連結保存構造は、単方向リストを使用して実装することもできます。挿入と削除操作はリストの両端で行います。キューポインタ front はリストの先頭を指す必要があります。

在这里插入图片描述

struct Node {
    ElementType Data;
    struct Node * Next;
}
struct QNode {//リンクキュー構造
    struct Node *rear;  //キューの末尾ノードを指す
    struct Node *front;  //キューの先頭ノードを指す
};
typedef struct QNode *Queue;
Queue PtrQ;

2. 操作#

(1) ヘッドノードを持たない連結キューの初期化(CreateQueue)#

Queue CreateQueue() {
    Queue Q;
    Q = (Queue)malloc(sizeof(struct QNode));
    Q->front = Q->rear = NULL;//両方のポインタがNULLです
    return Q;
}

(2) ヘッドノードを持たない連結キューへの要素の追加(AddQ)#

bool AddQ(Queue PtrQ, ElementType item) {
	struct Node *RearCell = PtrQ->rear;//末尾要素を指すポインタ
	struct Node *Temp = (struct Node *) malloc(sizeof(struct Node));
	Tmp->Data = X;
	Tmp->Next = NULL;
    if ( PtrQ->front == NULL ) {//キューが空の場合、最初の要素を追加します
        PtrQ->rear = PtrQ->front = Tmp;
    } else {
    	RearCell->Next = Tmp;
    	PtrQ->rear = Tmp;
    }
    return true;
}

(3) ヘッドノードを持たない連結キューから要素を削除する(DeleteQ)#

ElementType DeleteQ(Queue PtrQ) {
    struct Node * FrontCell;
    ElementType FrontElem;//先頭要素の値

    if (PtrQ->front == NULL) {//1.空かどうかを先に判断し、空の場合は削除操作を行えません
        printf("キューは空です");
        return ERROR;
    }
    FrontCell = PtrQ->front;
    if(PtrQ->front == PtrQ->rear) //キューに要素が1つだけある場合、削除後にキューを空にします
        PtrQ->front = PtrQ->rear = NULL;
    else
        PtrQ->front = FrontCell->Next;
    FrontElem = FrontCell->Data;
    free(FrontCell);    //削除されたノードの領域を解放します
    return FrontElem;
}
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。