http://blog.csdn.net/fisherwan/article/details/20055179
首先要感謝這位大牛的一篇博客,地址如下:http://blog.csdn.net/hguisu/article/details/7674195
當然還有網上一些其他的資料,今天自己寫了一下鏈式棧和鏈式隊列的程序。其中在釋放內存的時候遇到了些許問題,通過調,找出了原因,在這里我與大家分享一下。
(1)鏈式棧的相關代碼塊
Stack.h 頭文件——定義了節點結構和鏈式棧結構,以及基本操作函數的聲明部分
- #ifndef?_STACK_H_H??
- #define?_STACK_H_H??
- ??
- typedef?struct?Node??
- {??
- ????int?data;??
- ????struct?Node?*pNext;??
- }NODE,?*pNODE;??
- ??
- typedef?struct?Stack??
- {??
- ????pNODE?top;??
- }STACK,?*pSTACK;??
- ??
- ??
- void?InitStack(pSTACK?stack);??
- ??
- ??
- void?PushStack(pSTACK?stack,?int?data);??
- ??
- ??
- void?PopStack(pSTACK?stack,?int?*data);??
- ??
- ??
- int?IsEmptyStack(pSTACK?stack);??
- ??
- ??
- int?GetTopStack(pSTACK?stack);??
- ??
- ??
- void?FreeMemory(pSTACK?stack);??
- ??
- #endif??
Stack.cpp
源文件——定義鏈式棧的基本操作函數的定義
說明:一開始對棧初始化,但是這個棧是沒有頭節點的,直接定義了一個指針(top)剛開始指向NULL。
入棧的時候就是讓top指針始終指向棧頂元素,入棧的節點的指針指向top指針,這樣不斷的進行入棧操作,節點不斷增加,但是top指針一直是指針最后插入的節點。
出棧的時候就是從top指針指向的節點還是釋放,然后讓top指針指向被釋放節點的下一個節點,這樣節點不斷釋放,top指針不斷向下移動。
所以,棧就成了一個“先進后出”的結構。
- #include?"Stack.h"??
- #include?<stdlib.h>??
- #include?<stdio.h>??
- ??
- ??
- void?InitStack(pSTACK?stack)??
- {??
- ????stack->top?=?NULL;??
- }??
- ??
- ??
- void?PushStack(pSTACK?stack,?int?data)??
- {??
- ????pNODE?p_new?=?(pNODE)malloc(sizeof(NODE));??
- ??
- ????if?(NULL?==?p_new)??
- ????{??
- ????????printf("內存分配失敗!\n");??
- ????????exit(EXIT_FAILURE);??
- ????}??
- ??????
- ????p_new->data?=?data;??
- ????p_new->pNext?=?stack->top;???
- ????stack->top?=?p_new;??
- }??
- ??
- ??
- void?PopStack(pSTACK?stack,?int?*data)??
- {??
- ????pNODE?p_delete?=?stack->top;??
- ??
- ????if?(IsEmptyStack(stack))??
- ????????exit(EXIT_FAILURE);??
- ??
- ????*data?=?p_delete->data;??
- ????stack->top?=?p_delete->pNext;??
- ????free(p_delete);??
- ????p_delete?=?NULL;??
- }??
- ??
- ??
- int?IsEmptyStack(pSTACK?stack)??
- {??
- ????if?(stack->top?==?NULL)??
- ????????return?1;??
- ????else??
- ????????return?0;??
- }??
- ??
- ??
- int?GetTopStack(pSTACK?stack)??
- {??
- ????int?data;??
- ????if?(stack->top?==?NULL)??
- ????????exit(EXIT_FAILURE);??
- ??
- ????data?=?stack->top->data;??
- ????return?data;??
- }??
- ??
- ??
- void?FreeMemory(pSTACK?stack)??
- {??
- ????pNODE?p_delete?=?NULL;??
- ??
- ????while?(stack->top?!=?NULL)??
- ????{??
- ????????p_delete?=?stack->top;??
- ????????stack->top?=?p_delete->pNext;??
- ????????free(p_delete);??
- ????????p_delete?=?NULL;??
- ????}??
- }??
main.cpp?
測試程序——通過簡單的交互界面測試函數的功能
- #include?<stdio.h>??
- #include?"Stack.h"??
- ??
- int?main(void)??
- {??
- ????int?number,?i,?data,?flag;??
- ????STACK?s;??
- ????InitStack(&s);??
- ??????
- ????printf("請輸入入棧個數:");??
- ????scanf("%d",?&number);??
- ????for?(i=1;?i<number+1;?i++)??
- ????{??
- ????????printf("請輸入第%d個棧點元素值:",?i);??
- ????????scanf("%d",?&data);??
- ????????PushStack(&s,?data);??
- ????}??
- ??????
- ????PopStack(&s?,&data);??
- ????printf("出棧的元素值為:%d\n",?data);??
- ??
- ????data?=?GetTopStack(&s);??
- ????printf("當前棧頂元素值為:%d\n",?data);??
- ??
- ????FreeMemory(&s);??
- ????flag?=?IsEmptyStack(&s);??
- ????if?(flag)??
- ????????printf("內存釋放成功!\n");??
- ????else??
- ????????printf("內存釋放失敗!\n");??
- ??
- ????return?0;??
- }??
(2)鏈式隊列的相關代碼
Queue.h 頭文件——定義了節點結構和隊列結構,以及鏈式隊列的基本操作函數的聲明
- #ifndef?_QUEUE_H_H??
- #define?_QUEUE_H_H??
- ??
- typedef?struct?Node??
- {??
- ????int?data;??
- ????struct?Node?*pNext;??
- }NODE,?*pNODE;??
- ??
- typedef?struct?Queue??
- {??
- ????pNODE?front;??????
- ????pNODE?rear;??
- }QUEUE,?*pQUEUE;??
- ??
- ??
- void?InitQueue(pQUEUE?queue);??
- ??
- ??
- void?EnQueue(pQUEUE?queue,?int?data);??
- ??
- ??
- void?DeQueue(pQUEUE?queue,?int?*data);??
- ??
- ??
- int?IsEmptyQueue(pQUEUE?queue);??
- ??
- ??
- int?GetFrontQueue(pQUEUE?queue);??
- ??
- ??
- void?FreeMemory(pQUEUE?queue);??
- ??
- #endif??
Queue.cpp
源文件——定義了基本操作函數的定義
說明:一開始對鏈式隊列進行初始化,這里就創建了一個節點(但是記得后面釋放內存的時候這里也要釋放),創建了這個節點是為了方便后面的操作,這樣一開始隊列的頭指針和尾指針都指向了這個節點,但是此時的隊列是空的,就像循環鏈表里頭節點不參與運行是一樣的道理。
入隊列的時候就是進入的節點排在初始化時創建的節點后面,然后尾指針指針指著新進入的節點,但是頭指針不動,節點不斷進入隊列,尾指針不斷向后移動,保持尾指針一直指著剛進入的節點。
出隊列的時候就是讓頭指針指向的節點的指針指向要釋放節點的下一個節點,節點不斷出隊列,這里頭指針實質上并沒有移動,但是它指向的節點的指針一直在變化,一直保持者指向要釋放節點的下一個節點,但是這里要注意,就是當隊列中只剩下一個節點的時候(這里不包含初始化創建的那個節點),釋放了這個節點以后尾指針成了野指針,那么這個時候就要讓尾指針和頭指針指向同一位置,那么這樣判斷隊列是否為空的時候就是空了。
- ??
- #include?<stdlib.h>??
- #include?<stdio.h>??
- #include?"Queue.h"??
- ??
- ??
- void?InitQueue(pQUEUE?queue)??
- {??
- ????queue->front?=?(pNODE)malloc(sizeof(NODE));??
- ????queue->front->data?=?0;??
- ????queue->front->pNext?=?NULL;??
- ??
- ????if?(NULL?==?queue->front)??
- ????{??
- ????????printf("內存分配失敗!\n");??
- ????????exit(EXIT_FAILURE);??
- ????}??
- ??
- ????queue->rear?=?queue->front;??
- }??
- ??
- ??
- void?EnQueue(pQUEUE?queue,?int?data)??
- {??
- ????pNODE?p_new?=?(pNODE)malloc(sizeof(QUEUE));??
- ??
- ????if?(NULL?==?p_new)??
- ????{??
- ????????printf("內存分配失敗!\n");??
- ????????exit(EXIT_FAILURE);??
- ????}??
- ??
- ????p_new->data?=?data;??
- ????p_new->pNext?=?NULL;??
- ????queue->rear->pNext?=?p_new;??
- ????queue->rear?=?p_new;??
- }??
- ??
- ??
- void?DeQueue(pQUEUE?queue,?int?*data)??
- {??
- ????if?(IsEmptyQueue(queue))??
- ????????exit(EXIT_FAILURE);??
- ????pNODE?p_delete?=?queue->front->pNext;??
- ????*data?=?p_delete->data;??
- ????queue->front->pNext?=?p_delete->pNext;??
- ????if?(p_delete->pNext?==?NULL)??
- ????????queue->rear?=?queue->front;??
- ????free(p_delete);??
- ????p_delete?=?NULL;??
- }??
- ??
- ??
- int?IsEmptyQueue(pQUEUE?queue)??
- {??
- ????if?(queue->front?==?queue->rear)??
- ????????return?1;??
- ????else??
- ????????return?0;??
- }??
- ??
- ??
- int?GetFrontQueue(pQUEUE?queue)??
- {??
- ????int?data;??
- ????if?(IsEmptyQueue(queue))??
- ????????exit(EXIT_FAILURE);??
- ????data?=?queue->front->data;??
- ????return?data;??
- }??
- ??
- ??
- void?FreeMemory(pQUEUE?queue)??
- {??
- ????pNODE?p_delete?=?NULL;??
- ????while?(queue->front?!=?NULL)??
- ????{??
- ????????p_delete?=?queue->front;??
- ????????queue->front?=?p_delete->pNext;??
- ????????if?(p_delete->pNext?==?NULL)???
- ????????????queue->rear?=?NULL;??
- ????????free(p_delete);??
- ????????p_delete?=?NULL;??
- ????}??
- }??
main.cpp 測試程序——簡單的交互界面測試函數功能
- #include?<stdio.h>??
- #include?"Queue.h"??
- ??
- int?main(void)??
- {??
- ????int?number,?i,?data,?flag;??
- ????QUEUE?q;??
- ????InitQueue(&q);??
- ??????
- ????flag?=?IsEmptyQueue(&q);??
- ????if?(flag)??
- ????????printf("初始化成功!\n");??
- ??
- ????printf("請輸入入隊列個數:");??
- ????scanf("%d",?&number);??
- ????for?(i=1;?i<number+1;?i++)??
- ????{??
- ????????printf("請輸入第%d個隊點元素值:",?i);??
- ????????scanf("%d",?&data);??
- ????????EnQueue(&q,?data);??
- ????}??
- ??
- ????DeQueue(&q?,&data);??
- ????printf("出隊列的元素值為:%d\n",?data);??
- ??
- ????data?=?GetFrontQueue(&q);??
- ????printf("當前棧頂元素值為:%d\n",?data);??
- ??
- ????FreeMemory(&q);??
- ????if?(q.front?==?NULL?&&?q.rear?==?NULL)??
- ????????printf("內存釋放成功!\n");??
- ????else??
- ????????printf("內存釋放失敗!\n");??
- ??
- ????return?0;??
- }??