數據結構基礎四-----《線性結構的兩種常見應用之一 棧》

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


i.    定義

一種可以實現“先進後出”的存儲結構
棧 類似於竹筒倒豆子,最底下的最後倒出來

ii.    分類

靜態棧:以數組爲內核
動態棧:以鏈表爲內核

iii.    算法(這例講的是動態棧)


    1.刪除元素 pTop向下移一個位置
    2.加入元素 pTop 向上移一個位置
    3.指針pBottom 指向的是 棧底的結點 而這個結點通常沒有存儲數據,也就是最下面的有效結點的下一個結點,類似於鏈表的頭結點。
    4.如何判斷棧是否爲空??pTop == pBottom 時,鏈棧爲空。
    5.鏈式棧不存在滿還是不滿的

出棧/入棧圖解:


iv.    應用

           函數調用
           中斷
           表達式求值
           內存分配
           緩衝處理
           迷宮

示例:實現入棧/出棧操做

#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);//PSTACK  等價於struct STACK *
void push(PSTACK,int);
void traverse(PSTACK);
bool pop(PSTACK,int *);
void clear(PSTACK);

int main(void)
{
   int val;//用來保存出棧的元素
   //這句話一執行,內存中就會有一個變量,這個變量具有pTop和pBottom兩個成員。
   //但是這裏還沒有數據因爲還沒有對他進行初始化。
   STACK S;//STACK  等價於  struct Stack 
   init(&S);//對棧進行初始化  目的是造出一個空棧
   push(&S,1);//壓棧
   push(&S,2);
   push(&S,3);
   push(&S,4);
   push(&S,5);
   push(&S,6);
   push(&S,7);
   traverse(&S);

   if(pop(&S,&val))
   {
      printf("出棧成功,出棧的元素是:%d\n",val);
   }
   else
   {	
      printf("出棧失敗");
   }
   traverse(&S);//遍歷
   clear(&S);
   traverse(&S);
   return 0;
}

void init(PSTACK pS)
{
   pS->pTop = (PNODE)malloc(sizeof(NODE));
   if(pS->pTop ==NULL)
   {
      printf("內存分配失敗");
      exit(-1);	
   }
   else
   {
      pS->pBottom  = pS->pTop;
      pS->pTop->pNext = NULL;//pS->pBottom->pNext = NULL;  這兩者是等價的。
   }
}

void push(PSTACK pS,int val)
{
   PNODE pNew = (PNODE)malloc(sizeof(NODE));
   pNew ->data = val;
   pNew ->pNext = pS->pTop;//pS->pTop 不能改成pS->pBottom.
   pS->pTop = pNew;
   return;
}
 
void traverse(PSTACK pS)
{
   //定義一個指針p永遠指向最頂層的元素  或者說 指向的是 遍歷到的最頂上的元素。
   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
      return false;
}

//把pS 所指向的棧出棧一次,並把出棧的元素存入pVal形參所指向的變量中,
//如果出棧失敗,返回false,否則返回true。
bool pop(PSTACK pS,int * pVal)
{
   if(empty(pS))//pS  本身存放的就是 s 的地址。
   {
      return false;
   }else
    {
       //先讓pTop 指向棧頂的下一個元素 然後再將r所指向的棧頂元素的內存釋放掉。
		
       PNODE r = pS->pTop;
       pS->pTop = r ->pNext;
       *pVal = r->data;
       free(r);
       r = NULL;
       return true;
    }
}

void clear(PSTACK pS)
{
   if(empty(pS))
      return;
   else
   {
      PNODE p = pS->pTop;
      PNODE q = p->pNext;
      while(p != pS->pBottom)
      {
	 q = p->pNext;
	 free(p);
	 p = q;
      }
      pS->pTop = pS->pBottom;
   }	
}

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