郝斌數據結構--棧和隊列

線性結構的兩種常見應用之一 棧

定義 一種可以實現“先進後出”的存儲結構

分類

靜態棧 類似數組的結構

動態棧 類似鏈表的結構

棧的應用

(1)函數調用(所有的函數調用都是壓棧與出棧)

         所謂函數A調用函數B就是把A的最後執行的一個語句的地址與調用的B函數的

         所有內容壓到一個棧內部去執行,執行完畢出棧,然後地址出棧接着執行A函數

(2)中斷(中斷一個進程去執行下一個進程)

(3)表達式求值(表達式的數值部分與運算符會分開存放,利用兩個棧可以製作一個簡易計算器)

(4)內存分配(動態內存在堆中分配)

(5)緩衝處理

(6)迷宮(遊戲中的地圖,爲什麼走到一部分就走不動了)

 

# include <stdio.h>

# include <malloc.h>

# include <stdlib.h>

# include <stdbool.h>

 

typedef struct Node

{

int data;

struct Node *pNext;

 

}NODE, *PNODE;

 

typedef struct Stack

{

PNODE pTop;

PNODE pBottom;

}STACK, *PSTACK;

 

void init(PSTACK pS);

void push(PSTACK pS, int val);

bool pop(PSTACK pS, int *pVal);

bool clear(PSTACK pS);

bool traverse(PSTACK pS);

bool is_empty(PSTACK pS);

 

int main(void)

{

STACK S;

int val;

 

init(&S);

push(&S, 1);

push(&S, 2);

//push(&S, 3);

//push(&S, 5);

//push(&S, 6);

traverse(&S);

if (pop(&S, &val))

printf("出棧成功 值爲%d \n", val);

traverse(&S);

if (pop(&S, &val))

printf("出棧成功 值爲%d \n", val);

traverse(&S);

if (clear(&S))

printf("清除成功 \n");

traverse(&S);

return 0;

}

void init(PSTACK pS)

{

PNODE pNode = (PNODE)malloc(sizeof(NODE));

if (pS == NULL)

{

printf("內存分配失敗!\n");

exit(-1);

}

pS->pTop = pNode;

pS->pBottom = pNode;

pS->pBottom->pNext = NULL;// pS->pTop->pNext = NULL;

}

 

void push(PSTACK pS, int val)

{

PNODE pNode = (PNODE)malloc(sizeof(NODE));

if (pS == NULL)

{

printf("內存分配失敗!\n");

exit(-1);

}

pNode->data = val;

pNode->pNext = pS->pTop;

pS->pTop = pNode;

return;

}

bool traverse(PSTACK pS)

{

if (is_empty(pS))

{

return false;

}

PNODE pNode = pS->pTop;

while (pNode != pS->pBottom) //while (pNode->pNext != NULL)

{

printf("%d ", pNode->data);

pNode = pNode->pNext;

}

printf("\n");

}

 

bool pop(PSTACK pS, int *pVal)

{

if (is_empty(pS))

{

return false;

}

else

{

PNODE pNode = pS->pTop;

*pVal = pNode->data;

pS->pTop = pNode->pNext;

free(pNode);

return true;

}

}

 

bool is_empty(PSTACK pS)

{

if (pS->pTop == pS->pBottom)

{

printf("空棧\n");

return true;

}

else

{

return false;

}

}

// 類似於 pop

bool clear(PSTACK pS)

{

if (is_empty(pS))

{

return false;

}

PNODE pNode;

while (pS->pTop != pS->pBottom)

{

pNode = pS->pTop;

pS->pTop = pNode->pNext;

free(pNode);

printf("清除中...\n");

}

}

線性結構的兩種常見應用之二 隊列

定義 一種可以實現“先進先出”的存儲結構

分類

  • 鏈式隊列 用鏈表實現
  • 靜態隊列 用數組實現

    靜態隊列通常都必須使循環隊列

 

循環隊列的講解:

1. 靜態隊列爲什麼必須是循環隊列

2. 循環隊列需要幾個參數來確定 及其含義

        需要2個參數來確定

        front

        rear

3. 循環隊列各個參數的含義

    2個參數不同場合有不同的含義

        1)隊列初始化

               front和rear的值都是零

        2)隊列非空

              front代表的是隊列的第一個元素

              rear代表的是隊列的最後一個有效元素的下一個元素

        3)隊列空

              front和rear的值相等, 但不一定是空

4. 循環隊列入隊僞算法講解

        兩步完成

            1. 將值存入r所代表的 位置

            2.錯誤寫法 r=r+1

        正確寫法 r=(r+1)% 數組的長度

5. 循環隊列出隊僞算法講解

        f = (f+1)% 數組的長度

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

判斷 front 與 rear 的值是否相等

7. 如何判斷循環隊列是否已滿

預備知識 front的值可能比rear大 也可能比reat小 也可能相等

兩種方式

    1. 多增加一個標誌參數( f 和 r 相等)

    2. 少用一個元素 (通常使用第二種方式)

如果 r 和 f 緊挨着,則隊列已滿

if((r +1)% 數組長度 == f )

        已滿

else

       不滿

 

# include <stdio.h>

# include <stdbool.h>

# include <stdlib.h>

 

typedef struct Queue

{

int * pBase;

int front;

int rear;

}QUEUE;

 

void init(QUEUE *);

bool en_queue(QUEUE *, int val);

void traverse_queue(QUEUE *);

bool full_queue(QUEUE *);

bool out_queue(QUEUE *, int *);

bool empty_queue(QUEUE *);

 

int main(void)

{

QUEUE Q;

int val;

init(&Q);

en_queue(&Q, 1);

en_queue(&Q, 2);

en_queue(&Q, 3);

en_queue(&Q, 4);

en_queue(&Q, 5);

en_queue(&Q, 6);

en_queue(&Q, 7);

en_queue(&Q, 8);

traverse_queue(&Q);

if (out_queue(&Q, &val))

{

printf("出棧成功 值爲%d\n", val);

}

else

{

printf("出棧失敗\n");

}

traverse_queue(&Q);

return 0;

}

 

void init(QUEUE *pQ)

{

pQ->pBase = (int *)malloc(sizeof(int) * 6);

pQ->front = 0;

pQ->rear = 0;

return;

}

bool en_queue(QUEUE * pQ, int val)

{

if (full_queue(pQ))

{

return false;

}

else

{

pQ->pBase[pQ->rear] = val;

pQ->rear = (pQ->rear + 1) % 6;

return true;

}

}

 

void traverse_queue(QUEUE * pQ)

{

int i;

i = pQ->front;

while (i != pQ->rear)

{

printf("%d ", pQ->pBase[i]);

i = (i + 1) % 6;

}

printf("\n");

return;

}

 

bool full_queue(QUEUE *pQ)

{

if ((pQ->rear + 1) % 6 == pQ->front)

{

return true;

}

else

{

return false;

}

}

bool out_queue(QUEUE *pQ, int *pVal)

{

if (empty_queue(pQ))

{

return false;

}

else

{

*pVal = pQ->pBase[pQ->front];

pQ->front = (pQ->front + 1) % 6;

}

}

 

bool empty_queue(QUEUE *pQ)

{

if (pQ->front == pQ->rear)

{

return true;

}

else

{

return false;

}

}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章