C言語のキュー定義、シーケンシャルキュー、循環キュー、チェーンキュー構造(詳細)

1.シーケンシャルキューの共通基本操作と条件判定

队空:    Q.front=Q.rear
 队满:    Q.rear=Maxlen
 求队长:  Q.rear-Q.front

エンキュー:1)新しい要素は、リアで示される位置に追加されます
。2)リア=リア+ 1
チームのテールポインターにチームの 1つを加えたもの:1)フロントで示される要素が取り出されます。
2)フロント=フロント+ 1チームヘッドポインター+ 1
2.シーケンシャルキューのタイプ定義

#define MAXLEN 100
   typedef struct
    	{datatype  Q[MAXLEN];
    	  int front=0;
    	  int rear=0;
        } SeqQueue,*P;

Q:「偽のオーバーフロー」とは何ですか?それを解決するには?
回答:シーケンシャルチームでは、テールポインターが配列の上限に達すると、エンキュー操作はできなくなりますが、配列には実際には空の位置があり、これは「偽のオーバーフロー」と呼ばれます。
誤ったオーバーフローを解決する方法-循環キューを採用

循環キュー

これをリングエンドツーエンドで接続したものと考え、このベクトルを循環ベクトルと呼び、そこに格納されているキューを循環キューと呼びます。ここに画像の説明を挿入

新しい問題:循環キューでは、空のチームはQ.front = Q.rearで特徴付けられます。チームがいっぱいになると、Q.front = Q.rearも存在します。判定条件があいまいに表示されます!
3つの解決策があります:
①カウンターを使用するキュー(即ち、キュー長)内の要素の数を記録するステップと、
配置されたフラグを追加する際に削除設定されている0に設定すると②、挿入、電流が属する=状況Q.rear Q.frontを識別することができる
③人間の廃棄物ユニットを、チームのフル機能は、Q.front =(Q.rear + 1)%MAXLENに変更できます。

スキーム3は実際に頻繁に使用されます(ユニットは人為的に浪費されます)。
前と後ろのポイントの1つは実エレメントを指し、他のポイントはアイドルエレメントを指します。

队空条件 :  Q.front =Q. rear       (初始化时:Q.front = Q.rear )
队满条件: Q.front = (Q.rear+1) % N         (N=maxsize)
队列长度(即数据元素个数):L=(N+Q.rear-Q.front)% N
 

ここに画像の説明を挿入
例1:配列Q [n]は循環キューを表すために使用され、fは現在のキューの先頭要素の前の位置、rは末尾要素の位置です。キュー要素として算出未満nよりも素子のキュー数は、と仮定し
ている:A)R&LT-F(B)(N + F-R&LT)%N-
(C)N- + R&LT-F(D)(N + R&LT-F)%のn-
へ4つの式のどれが最も合理的ですか?
r≥fの場合、(A)は妥当です
。r<f、(C)の場合、2つの状況を組み合わせると、式(D)が最も妥当です。
例2:循環キューで、チームヘッドポインターがチームヘッドを指すように合意されている場合要素の前の位置。その後、循環キューから要素を削除し、操作がするキューのポインタヘッド移動除去要素
ここに画像の説明を挿入
ここに画像の説明を挿入

循環キューを形成するには?
循環キューでデキューおよびエンキュー操作を実行する場合、ヘッドポインタとテールポインタは引き続き1ずつ増加して前に進む必要があります。
頭から尾へのポインタがベクトルの上限(MAXLEN-1)を指している場合、1を追加した結果はベクトルの下限0を指すことになります。
1を追加した結果は、ベクトルの下限0を指す方法です。

*(front+1)%M       (rear+1)%M*

ここに画像の説明を挿入

空のチーム:Q.front = Q.リア
チームがいっぱい:Q.front =(Q.rear + 1)%MAXLENエンキュー
:Q.rear =(Q.rear + 1)%MAXLENデキュー
:Q.front =(フロント+ 1)%MAXLEN;
キャプテンを探す:(Q .リア-Q。フロント+ MAXLEN)%MAXLEN

-3)循環キューのタイプ定義

#define MAXLEN 100
typedef struct
	{datatype *data[MAXLEN];
	  int front;
	  int rear;
     int n;/*判队空,队满的另一方法*/
   } CseqQueue

-4)循環キュー操作の実装

①キューを初期化する

CseqQueue * IniQueue (CseqQueue *Q) 
{                                                    //构造空队列
  Q= (CseqQueue *) malloc(sizeof(CseqQueue ));
  Q->rear = Q->front = 0;
  return Q;
}

ここに画像の説明を挿入
②チームは空です

int QueueEmpty (CseqQueue *Q ) 
{
    return(Q->rear == Q->front);
}

③チームは満員

int QueueFull (CseqQueue *Q ) 
{
    return((Q->rear+1) % MAXLEN == Q->front);
}

④チームは満員

int QueueFull (CseqQueue *Q ) 
{
    return( (Q->n) == MAXLEN);
}

⑤エントリー

int InQueue (CseqQueue *Q, datatype x ) 
{
    if (QueueFull (Q) ) 
          return 0;
   else 
      {Q->data[Q->rear] = x; 
        Q->rear = ( Q->rear+1) % MAXLEN; 
        Q->n++;
        return 1;
      }
 }

⑥チームを離れる

int DeQueue (CseqQueue *Q, datatype *x ) 
{
    if ( QueueEmpty (Q) ) 
        return 0;
   else
       {*x = Q->data[Q->front]; 
         Q->front = ( Q->front+1) % MAXLEN; 
         Q->n--;
         return 1;
      }
}

theチームのリーダーに

int GetFront (CseqQueue *Q, datatype *x ) 
{
     if ( QueueEmpty (Q) )
          return 0;
     *x = Q->data[Q->front];
     return 1;
}

queueキューの長さを見つける

int QueueLength (CseqQueue  *Q)
{
  return( (Q->rear – Q->front + MAXSIZE) % MAXSIZE);
}

チェーンキュー構造

(1)チェーンキュー構造**
チェーンキューの概略図ここに画像の説明を挿入
(2)チェーンキューの説明
シーケンシャルキューと同様に、これらの2つのポインターも一緒にカプセル化し、リンクキューのタイプLinkQueueを構造タイプとして定義します。

typedef struct queuenode
      { datatype  data;
         struct queuenode *next;
       }queuenode;
   typedef struct
      {  queuenode  *front;
          queuenode  *rear;
       }Linkqueue;

3)チェーンキューに実装された基本操作
1)空のキュー(ヘッドノードの空のキュー)を構築します。

  void initqueue(Linkqueue  *q)
     { q.front=(queuenode *)malloc(sizeof(queuenode));
       q.rear=q.front
       q.front->next=q.rear->next= NULL;
     }

ここに画像の説明を挿入
2)エンキュー操作
ここに画像の説明を挿入
エンキュー操作アルゴリズム

void inqueue(Linkqueue  *q,datatype  x)
     {queuenode *p
      p=(queuenode * )malloc(sizeof(queuenode));
      p–>data=x;
      p–>next=NULL;
      q.rear–>next=p;
      q.rear=p;
     }

3)キューの判定

int queueempty(Linkqueue  *q)
    {
      return (q.front->next= =NULL &&
                  q.rear->next= =NULL);
     }
  1. デキュー操作ここに画像の説明を挿入
    4)デキュー操作アルゴリズム

データ型デキュー(Linkqueue * q)
{datatype x;
queuenode * p
if(queueempty(q))
{printf( "Queue is empty"); return;}
p = q.front–> next;
x = p–> data;
q.front–> next = p–> next;
if(q.rear = = p)/ テールノードを削除 /
q.rear = q.front;
free§;
return x;
}

ご不明な点がございましたら、メッセージを残して、時間内に修正してください

元の記事を10件公開 12 件を獲得 1856年を訪問

おすすめ

転載: blog.csdn.net/qq_44236958/article/details/89167223