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);
}
チェーンキュー構造
**
チェーンキューの概略図
(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);
}
- デキュー操作
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;
}
ご不明な点がございましたら、メッセージを残して、時間内に修正してください