/*
時間:2012/07/21 14:42
目的:自己模擬一個動態棧
*/
# include <stdio.h>
# include <malloc.h>
# include <stdlib.h>
typedef struct Node //創建一個節點類型的結構體
{
int data; //數據域
struct Node * pNext; //指針域
}NODE, * PNODE;
typedef struct Stack
{
PNODE pTop; //指向棧頂的指針
PNODE pBottom; //指向棧底的指針
}STACK, * PSTACK;
void init(PSTACK);
void push(PSTACK, int);
void traverse(PSTACK);
bool pop(PSTACK, int *);//如果棧爲空的話,出棧操作將無法進行。因此,此方法要有返回值來表示出棧操作是否成功。
void toPop(PSTACK);
void clear(PSTACK pS);
bool isEmpty(PSTACK pS);
int main(void)
{
STACK s; //相當於 struct Stack s;
init(&s);
push(&s, 5);
push(&s, 7);
traverse(&s);
toPop(&s);
toPop(&s);
toPop(&s);
for (int i=1; i<10; i++)
push(&s, i);
traverse(&s);
clear(&s);
traverse(&s);
return 0;
}
void init(PSTACK pS)
{
pS->pBottom = (PNODE)malloc( sizeof(NODE) );
if (NULL == pS->pBottom)
{
printf("內存分配失敗,程序終止。");
exit(-1);
}
else
{
pS->pTop = pS->pBottom;
pS->pBottom->pNext = NULL; //設置尾節點的指針域爲空 【注】尾節點無實際意義,只是爲了方便程序的操作。
}
}
void push(PSTACK pS, int val)
{
PNODE pNew = (PNODE)malloc( sizeof(NODE) );
if (NULL == pNew)
{
printf("內存分配失敗,程序終止。");
exit(-1);
}
else
{
pNew->data = val; //設置新入棧節點的數據域
pNew->pNext = pS->pTop; //設置新入棧節點的指針域 指向 原棧頂的節點
pS->pTop = pNew; //設置新入棧的節點爲棧頂的節點
}
}
void traverse(PSTACK pS)
{
PNODE p = pS->pTop;
while (p != pS->pBottom)
{
printf("%d ", p->data);
p = p->pNext;
}
printf("\n");
}
bool isEmpty(PSTACK pS)
{
if (pS->pTop == pS->pBottom) //棧爲空時
{
return true;
}
else
{
return false;
}
}
/*
參數:pS爲棧的指針
oldVal爲指向 被出棧節點的數據域 的指針,通過*oldVal即可設置被出棧節點的數據域的值,從而向調用函數返回被出棧節點的數據域的值。
返回值:爲true時,出棧操作成功;爲false時,出棧操作失敗,即棧中沒有有效的元素,沒有有效的節點。
*/
bool pop(PSTACK pS, int * oldVal)
{
if ( isEmpty(pS) ) //棧爲空時
{
return false;
}
else
{
PNODE p = pS->pTop; //把原棧頂節點的指針賦值給一個臨時變量,方便在後面釋放內存
*oldVal = pS->pTop->data; //把原棧頂節點的數據域的值返回給調用的函數中的val變量,即main方法中的val變量。
pS->pTop = pS->pTop->pNext; //設置棧頂節點 爲 原棧頂節點所指向的下一個節點
free(p); //釋放原棧頂節點所佔用的內存
//p = NULL;
return true;
}
}
void toPop(PSTACK pS)
{
int val;
if ( pop(pS, &val) )
printf("被出棧的元素是:%d\n", val);
else
printf("已經是空棧了,不用再進行出棧操作了!\n");
}
/*
清空棧的方法
*/
void clear(PSTACK pS)
{
if ( isEmpty(pS) )
return; //棧本來就爲空時,讓方法直接返回。減少因爲運行下面的代碼,所帶來的時間和內存的消耗。
PNODE p = pS->pTop;
PNODE q = NULL; //q存次棧頂節點
while (p != pS->pBottom)
{
q = p->pNext; //把棧頂節點下一個節點的指針存起來,以避免棧頂節點被釋放後無法找到它的下一個節點。
free(p); //釋放棧頂節點所佔的內存
p = q; //更新棧頂節點 爲 它的下一個節點
}
pS->pTop = pS->pBottom; //【注】千萬別忘記把pS->pTop指向尾節點。因爲,此時棧已經被清空了,已經沒有任何有效元素了。
}
/*
程序的運行結果:
==========================================================================
7 5
被出棧的元素是:7
被出棧的元素是:5
已經是空棧了,不用再進行出棧操作了!
9 8 7 6 5 4 3 2 1
==========================================================================
總結:
-----------------------------------------------------------------------------------------------
棧:後進先出
靜態棧:用數組實現的。 用靜態分配內存的方式,聲明一個數組作爲棧
動態棧:用鏈表實現的。 用動態分配內存的方式,構造一個鏈表作爲棧
-----------------------------------------------------------------------------------------------
*/