C動態棧

 

/*
時間: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
==========================================================================

總結:
-----------------------------------------------------------------------------------------------
棧:後進先出
靜態棧:用數組實現的。  用靜態分配內存的方式,聲明一個數組作爲棧
動態棧:用鏈表實現的。  用動態分配內存的方式,構造一個鏈表作爲棧
-----------------------------------------------------------------------------------------------
*/

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