C語言利用隊列的操作實現隊列中元素的逆置(逆序輸出)
題目均在sdibt acm oj上AC,參考《深入淺出數據結構和算法》教材,逐個複製即可運行,歡迎評論指正!
Description
假設隊列中有n個整數,編寫算法實現將隊列中的元素逆置,要求利用棧實現。
要求:
(1)編寫函數分別實現隊列初始化、判斷隊空、判斷隊滿、入隊、出隊的操作;
(2)編寫函數分別實現棧的初始化、判斷棧空、棧滿、入棧、出棧操作;
(3)主函數調用上述函數,實現所給問題。
Input
輸入隊列中元素的個數n
依次輸入n個數,建立隊列。
Output
依次輸出逆置後的隊列中的元素。
Sample Input
6
1 2 3 4 5 6
Sample Output
6 5 4 3 2 1
HINT
若想完成逆置,並且使用隊列和棧的操作,我們必須使用隊列的先進先出原則,和棧的先進後出原則。
那麼我們兩者結合,使用棧來逆置,逆置後的元素隨即入隊,最後對隊列進行一個輸出元素的操作,這樣就能完成逆置這一操作。
結構體定義如下,隊列+棧:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20
#define STACK_SIZE 30
///////////////////////////////////////
//定義隊列的結構體
typedef struct Squeue{
int data[MAXSIZE];//隊列內元素的最大長度
int front;//隊頭
int rear;//隊尾
}Squeue;
//定義棧(順序棧)的結構體
typedef struct{
int *base;
int *top; //棧頂指針
int size;
}seqStack;
///////////////////////////////////////
棧的基本幾個操作:初始化、出入棧、取棧頂元素
int InitStack(seqStack *s){
s->base = (int *)malloc(STACK_SIZE* sizeof(seqStack));//動態分配30個單位的stack
//省略是否空間滿
s->top = s->base;//棧頂和棧尾相同,棧裏面沒有元素
s->size = STACK_SIZE;
return 1;
}
int Push(seqStack *s,int x){
*s->top = x;
s->top++;
return 1;
}
int Pop(seqStack *s,int *x){
if(s->top == s->base)return 0;
else{
s->top--;
*x = *s->top;
return 1;
}
}
int GetTop(seqStack *s, int *x){
if(s->top==s->base)
return 0;
else{
*x=*(s->top-1);
return 1;
}
}
隊列的幾個基本操作:初始化、判斷空狀態、出入隊
//初始化隊列
void InitQueue(Squeue *Q)
{
Q->front = Q->rear = 0;
}
//判斷隊列是否爲空
int isQueueEmpty(Squeue *qu)
{
if(qu->front == qu->rear)
{
return 1;
}
else
{
return 0;
}
}
//元素入隊操作
int EnQueue(Squeue *qu,int x)
{
//若隊滿則無法入隊——當前個數已經超過最大數量,
//就會出現mod(Maxsize)的結果是隊頭指針
//比如,隊頭是1,最大長度是12,若入隊第13個元素,則會出現13mod12==1(和隊頭相等)的情況
//這樣就會return false
if((qu->rear + 1) % MAXSIZE == qu->front)
{
return 0;
}
qu->rear = (qu->rear + 1) % MAXSIZE;
qu->data[qu->rear] = x;
return 1;
}
//元素出隊操作
int deQueue(Squeue *qu,int *x)
{
//若隊空則無法出隊
if(qu->front == qu->rear)
{
return 0;
}
qu->front = (qu->front + 1) % MAXSIZE;
*x = qu->data[qu->front];
return 1;
}
主函數:入棧->出棧、入隊->出隊輸出完成逆置
int main()
{
int i , n , x , a;
scanf("%d",&n);
Squeue q;
seqStack s;
InitStack(&s);
InitQueue(&q);
//順序的入棧
for(i = 0;i < n;i++)
{
scanf("%d",&a);
Push(&s,a);
}
int stackNumber;
for(i=0;i<n;i++)
{
Pop(&s,&stackNumber); //逆序的出棧(遵頊先進後出原則)
EnQueue(&q,stackNumber);//逆序的入隊
}
while(!isQueueEmpty(&q))
{
deQueue(&q,&x); //逆序的出隊(遵循先進先出原則)
printf("%d ",x); //完成逆轉,輸出!
}
return 0;
}