數(shù)據(jù)結構學習第二彈 棧與隊列(2)

隊列

隊列掘殴,可以說是日常生活中最常見的一種現(xiàn)象碰辅,隊列與平時排隊有著相似的特點。隊列也是一種運算受限制的線性表净嘀,與棧不同的是,其是限制在兩端操作的線性表

定義:

隊列就跟日常排隊有一樣的特點:先進先出侠讯,只允許在隊列的一端插入數(shù)據(jù)元素(入隊)挖藏,只允許在隊列的另一端刪除數(shù)據(jù)元素(出隊),可刪除的一端稱為隊頭厢漩,可插入的一端稱為隊尾膜眠。
隊列的修改總是按照先進先出的原則進行的,也就是說新的元素溜嗜,只能添加在對尾宵膨,每次離開的元素只能從隊頭離開,就和排隊打飯一樣炸宵,不過這個隊不允許中途離隊辟躏,比如隊列中加入元素a1,a2,a3……an,a1就是隊頭元素焙压,an就是隊尾元素,退出隊列的順序也只能是a1,a2……an.

隊列的基本操作

  • InitQueue(Q): 構造一個空隊列
  • EmptyQueue(Q): 判斷一個隊列是否為空
  • LengthQueue(Q): 求隊列的長度
  • FrontQueue(Q,e): 獲取隊頭元素
  • EnQueue(Q,e): 入隊操作
  • DeQueue(Q,e): 出隊操作

和棧同理鸿脓,隊列也可以分為順序隊列和鏈隊列。

順序隊

順序存儲結構的類型定義

#define MAXSIZE 20          //單純的空間大小涯曲,并不能代表隊列中的元素有多少
typedef int ElemType;
typedef struct
{
    ElemType data[MAXSIZE];
    int front,rear;         //尾指針和頭指針
}SeQueue;

具體操作

#define OK 1
#define ERROR 0
typedef int Status;
//將隊列初始化置為空
Status InitQueue(SeQueue *q)
{
    q->front = 0;
    q->rear = 0;
    return OK;
}
//判斷隊列是否為空
int EmptyQueue(SeQueue *q)
{
    if(q->front == q->rear)
        return 1;
    else
        return 0;
}
//獲取隊列長度
int LengthQueue(SeQueue q)
{
    return q.rear-q.front;          //隊尾指針減去隊頭獲得長度
}
//入隊操作
Status EnQueue(SeQueue *q,ElemType e)
{
    if(q->rear == MAXSIZE)          //隊滿
    {
        printf("FULL\n");
        return ERROR;
    }
    q->data[q->rear] = e;           //入隊操作
    q->rear++;                      //隊尾指針向后移
    return OK;
}
//獲取隊頭元素
Status FrontQueue(SeQueue *q,ElemType *e)
{
    if(EmptyQueue(q))               //隊空
    {
        printf("Empty\n");
        return ERROR;
    }
    *e = q->data[q->front];
    return OK;
}
//出隊操作
Status DeQueue(SeQueue *q,ElemType *e)
{
    if(EmptyQueue(q))
    {
        printf("Empty\n");
        return ERROR;
    }
    *e = q->data[q->front];         //出隊操作
    q->front++;
    return OK;
}

缺點:

由于出隊操作和入隊操作中野哭,頭尾指針只會增加,所以會導致被刪除元素無法被重新利用幻件,所以有一種情況拨黔,當隊列中元素個數(shù)少于最大空間時,但也會因為尾指針超過空間上限而不能做入隊操作绰沥。所以這種隊列還是很弱的篱蝇,但是如果表示成循環(huán)隊列就能克服這種情況了

循環(huán)隊列

(腦補長成一條的隊列被拗成環(huán)的樣子)當隊尾指針移動到空間的上限位置時贺待,因為這是一個環(huán),所以隊尾指針還可以繼續(xù)移動下去進入到數(shù)組最小下標的位置(用取模來實現(xiàn))零截,這樣就可以最大限度的利用存儲空間了麸塞。
還有一個要解決的問題就是如何判斷隊滿,有兩種解決方案:

  • 因為是環(huán)所以當頭尾指針相等就是隊滿的情況了涧衙,但是一開始的
    時候如果頭尾指針相等就是隊空了哪工,所以可以多開設一個一個變量
    來記錄隊空還是隊滿
  • 還有一個比較簡便的方法就是空出一格來,這樣隊滿和隊空就可
    以被區(qū)分了(下面有這種來處理隊滿情況)

循環(huán)隊列的具體操作:

循環(huán)隊列也是用的順序存儲結構弧哎,所以類型定義和順序隊是基本一樣的雁比,而在部分運算操作上就有些不同了。

//隊列長度
int LengthQueue(SeQueue q)
{
    int len = (q.rear-q.front+MAXSIZE)%MAXSIZE;
    return len;
}
//入隊操作
Status EnQueue(SeQueue *q,ElemType e)
{
    if((q->rear+1)%MAXSIZE == q->front)//犧牲多一個空間來判斷隊滿的情況
        return ERROR;
    q->data[rear] = e;              //入隊
    q->rear = (q->rear+1)%MAXSIZE;  //尾指針加一并保證循環(huán)狀態(tài)
    return OK;
}
//出隊操作
Status DeQueue(SeQueue *q,ElemType *e)
{
    if((q->rear+1)%MAXSIZE == q->front)
        return ERROR;
    *e = q->data[q->front];         //出隊
    q->front = (q->front+1)%MAXSIZE;//頭指針加一并保證循環(huán)意義
}

鏈隊

顧名思義撤嫩,用鏈表來表示的隊列被稱為鏈隊偎捎。鏈隊的結點結構和單鏈表是一樣的,只不過隊列的插入和刪除操作是分別在隊尾和隊頭進行的序攘。因此除了設置頭指針外還要設置尾指針在指向隊尾茴她,為了方便,這里采用有頭結點的單鏈表來表示隊列

隊列的鏈式存儲結構類型定義

typedef int ElemType;       //數(shù)據(jù)類型
typedef struct node
{
    ElemType data;          //數(shù)據(jù)域
    struct node *next;      //指針域
}QueueNode;     
typedef struct
{
    QueueNode *front;       //頭指針
    QueueNode *rear;        //尾指針
}LinkQueue;

鏈隊運算的具體操作

//初始化隊列置為空
Status InitQueue(LinkQueue *q)
{
    QueueNode *head;
    head = (QueueNode*)malloc(sizeof(QueueNode));//為頭結點開辟存儲空間
    if(!head)               //空間申請失敗
        return ERROR;
    head->next = NULL;      //頭結點指針域置為空
    q->front   = head;      //頭指針指向頭結點
    q->rear    = head;      //尾指針指向頭結點
    return OK
}
//判斷隊列是否為空
Status EmptyQueue(LinkQueue *q)
{
    return q->rear == q->front;
}
//獲取隊頭元素
Status FrontQueue(LinkQueue *q.ElemType *e)
{
    if(EmptyQueue(q))       //隊列為空
        return ERROR;
    *e = q->front->data;
    return OK;
}
//元素入隊
Status EnQueue(LinkQueue *q,ElemType e)
{
    QueueNode *s;
    s = (QueueNode*)malloc(sizeof(QueueNode));  //為新結點申請空間
    if(!s)                  //申請空間失敗
        return ERROR;
    s->data = e;            //新結點數(shù)據(jù)域賦值
    s->next = NULL;         //新結點指針域置為空
    q->next->next = s;      //新結點插入到隊尾
    q->rear = s;            //更新尾結點
    return OK;
}
//元素出隊
Status DeQueue(LinkQueue *q,ElemType *e)
{
    if(EmptyQueue(q))           //隊空
        return ERROR;
    QueueNode *s;
    s = q->front->next;         //s指向隊頭元素
    q->front->next = s->next;   //將s指向的元素移出隊列
    if(q->rear = s)             //如果移出的元素是最后一個
        q->rear = q->front;     //隊尾指針指向頭結點
    *e = s->data;               //用e返回移出的元素值
    free(s);
    return OK;
    
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末程奠,一起剝皮案震驚了整個濱河市败京,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梦染,老刑警劉巖赡麦,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異帕识,居然都是意外死亡泛粹,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門肮疗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晶姊,“玉大人,你說我怎么就攤上這事伪货∶茄茫” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵碱呼,是天一觀的道長蒙挑。 經(jīng)常有香客問我,道長愚臀,這世上最難降的妖魔是什么忆蚀? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上馋袜,老公的妹妹穿的比我還像新娘男旗。我一直安慰自己,他們只是感情好欣鳖,可當我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布察皇。 她就那樣靜靜地躺著,像睡著了一般泽台。 火紅的嫁衣襯著肌膚如雪让网。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天师痕,我揣著相機與錄音,去河邊找鬼而账。 笑死胰坟,一個胖子當著我的面吹牛,可吹牛的內容都是我干的泞辐。 我是一名探鬼主播笔横,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼咐吼!你這毒婦竟也來了吹缔?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤锯茄,失蹤者是張志新(化名)和其女友劉穎厢塘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肌幽,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡晚碾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喂急。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片格嘁。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖廊移,靈堂內的尸體忽然破棺而出糕簿,到底是詐尸還是另有隱情,我是刑警寧澤狡孔,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布懂诗,位于F島的核電站,受9級特大地震影響苗膝,放射性物質發(fā)生泄漏响禽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芋类。 院中可真熱鬧隆嗅,春花似錦、人聲如沸侯繁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贮竟。三九已至丽焊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間咕别,已是汗流浹背技健。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惰拱,地道東北人雌贱。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像偿短,于是被迫代替她去往敵國和親欣孤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內容