數據結構4——棧和隊列

文章目錄

  • 定義:
    • 一種可以實現“先進後出”的存儲結構。
  • 分類:
    • 靜態棧
    • 動態棧
  • 算法:
    • 出棧
    • 壓棧
      在這裏插入圖片描述
      在這裏插入圖片描述
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Node{
    int data;
    struct Node * pNext;
}NODE, * PNODE;

typedef struct Stack{
    PNODE pTop;// pTop永遠指向棧頂元素
    PNODE pBottom; // pBottom永遠指向棧底元素的下一個無意義的元素(類似於頭結點,方便操作。)
}STACK, * PSTACK;
void init(PSTACK);
void push(PSTACK,int);
void traverse(PSTACK);
bool pop(PSTACK,int *);

int main(void){
    STACK S;
    int val;
    init(&S); // 目的是造出一個空棧
    push(&S,1); // 壓棧
    push(&S,2);
    traverse(&S); // 遍歷輸出
    pop(&S,&val); // 出棧
    clear(&S); // 清空
    return 0;
}

void init(PSTACK pS){
    pS->pTop = (PNODE)malloc(sizeof(NODE));
    if(NULL == pS->pTop){
        printf("動態內存分配失敗!\n");
        ext(-1);
    }else{
        pS->pBottom = pS->pTop;
     	pS->pTop->pNext = NULL;
    }
}
void push(PSTACK pS,int val){
    PNODE pNew = (PNODE)malloc(sizeof(NODE));
    pNew->data = val;
    pNew->pNext = pS->pTop; // pS->pTop指向頭結點的指針賦給pNew->pNext
    pS->pTop = pNew;
    return;
}
void traverse(PSTACK pS){
    PNODE p = pS->pTop;
    while(p != pS->pBottom){
        printf("%d",p->data);
        p = p-pNext;
    }
    printf("\n");
    return;
}
bool empty(PSTACK pS){
    if(pS->pTop == pS->pBottom){
        return true;
    }else{
        reurn false;
    }
}

// 把pS所指向的棧出棧一次,並把出棧的元素存入pVal形參所指向的變量中。
bool pop(PSTACK pS,int * pVal){
    if(empt(pS)){
        return false;
    }else{
        PNODE r= pS->pTop;
        *pVal = r->data;
        pS->pTop = r->pNext;
        free(r);
        r = NULL;
        return true;
    }
}
void clear(PSTACK pS){
    if(empty(pS)){
        return;
    }else{
        PNODE p = pS->pTop;
        PNODE q = NULL;
        while(p != pS->pBottom){
            q = p->pNext;
            free(p);
            p = q;
        }
        pS->pTop = pS->pBottom;
    }
}
  • 應用
    • 函數調用
    • 中斷
    • 表達式求值(計算器算法)
    • 內存分配
    • 緩衝處理
    • 迷宮

隊列

  • 定義:
    • 一種可以實現“先進先出”的存儲結構。
  • 分類:
    • 鏈式隊列 ——用鏈表實現
    • 靜態隊列——用數組實現
      • 靜態隊列通常都必須是循環隊列。
  • 應用:
    • 所有和時間有關的操作都有隊列的影子。
  • 循環隊列
    • 靜態隊列爲什麼必須是循環隊列
      在這裏插入圖片描述
      在這裏插入圖片描述

    • 循環隊列需要幾個參數確定

      • 兩個參數(front、rear)
    • 循環隊列各個參數的含義

        - 各個參數在不同場合有不同的含義
        - 隊列初始化:
        	- front和rear的值都是0。
        - 隊列非空:
        	- front代表隊列的第一個元素,rear代表隊列最後一個有效元素的下一個元素。
        - 隊列空
        	- front和rear的值相等,但不一定是0。
      
    • 循環隊列入隊僞算法
      在這裏插入圖片描述

    • 循環隊列出隊僞算法(取餘的操作着實很秀,我想不到
      在這裏插入圖片描述
      在這裏插入圖片描述妙啊

    • 如何判斷循環隊列是否爲空

      • front和rear的值相等。
    • 如何判斷循環隊列是否已滿(更妙了
      在這裏插入圖片描述

隊列算法:

#include <stdio.h>
#include <malloc.h>
typedef struct Queue{
    int * pBase;
    int front;
    int rear;
}QUEUE; 
void init(QUEUE *);
bool en_queue(QUEUE *,int); // 入隊
void traverse_queue(QUEUE *);
bool full_queue(QUEUE *);
bool out_queue(QUEUE *,int *);
bool emput_queue(QUEUE *);

int main(void){
    QUEUE Q;
    init(&Q);
    en_queue(&Q,1);
    traverse_queue(&Q);
    
    return 0;
}

void init(QUEUE *pQ){
    pQ->pBase = (int *)malloc(sizeof(int) * 6);// 數組
    pQ->front = 0;
    pQ->rear = 0;
}
bool full_queue(QUEUE *pQ){
    if((pQ->rear+1)%6 == pQ->front)
        return true;
    else
        return false;
}
bool en_queue(QUEUE *pQ,int val){
    if(full_queue(pQ)){
        printf("入隊失敗!\n");
        return false;
    }else{
        pQ->pBase[pQ->rear] = val;
        pQ->rear = (pQ->rear+1)%6;
        return true;
    }
}
void traverse_queue(QUEUE * pQ){
    int i = pQ->front;
    while(i != pQ->rear){
        printf("%d",pQ->pBase[i]);
        i = (i+1)%6;
    }
    printf("\n");
    return;
}
bool emput_queue(QUEUE * pQ){
    if(pQ->front == pQ->rear)
        return true;
    else
        return false;
}
bool out_queue(QUEUE * pQ,int * pVal){
    if(emput_queue(pQ)){
        return false;
    }else{
        *pVal = pQ->pBase[pQ->front];
        pQ->front = (pQ->front+1)%6;
        return true;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章