1. 程式人生 > >資料結構與演算法分析:線性結構(3)

資料結構與演算法分析:線性結構(3)

堆疊

1.計算機如何進行表示式求值

    算術表示式5+6/2-3*4

  • 由兩類物件構成:運算數,運算子號
  • 不同運算子號優先順序不同

   ①中綴表示式:把運算子號放在兩個運算數之間:a+b*c-d/e      

      字尾表示式:把運算子號放在兩個運算數之後:abc*+de/-

      字尾表示式求值策略:從左向右掃描,逐個處理運算數和運算子號

   ②啟示:

     

 需要有種儲存方式,能順序儲存數,並在需要時“倒序”輸出

 

2.堆疊的抽象資料型別描述

      特點:LIFO

     資料物件集:一個有0個或多個元素的有窮線性表

     操作集:

        1​​​​​​.Stack CreateStack(int MaxSize);

        2.int IsFull(Stack S,iint MaxSize);

        3.void Push(Stack S,ElementType item);

       4.int IsEmpty(Stack S);

       5.ElementType Pop(Stack S);​ 

   

  ①棧的順序儲存實現

      由一個一位陣列和一個記錄棧頂元素位置的變數組成。

#define MaxSize 100
#define ElementType int

typedef struct SNode* Stack;
struct SNode{
ElementType Data[MaxSize];
int Top;
};

  (1)入棧 

void Push(Stack PtrS,ElementType item){
 if(PtrS->Top==MaxSize-1){
    printf("棧滿");
    return;
 }else{
   PtrS->Data[++(PtrS->Top)]=item;
   return ;
 }
}

  (2)出棧

ElementType Pop(Stack PtrS){
if(PtrS->Top==-1){
    printf("棧空");
    return -1;
}else{
 return (PtrS->Data[--(PtrS->Top)]);
}
}

  (3)例

          要求用一個數組實現兩個堆疊,要求最大地利用陣列空間

          做法:使兩個棧從分別從陣列的兩頭開始向中間生長;當兩個棧的棧頂指標相遇時,表示兩個棧滿

#define MaxSize 100
#define ElementType int

struct DStack{
ElementType Data[MaxSize];
int Top1;
int Top2;
}S;
void Push(struct DStack* PtrS,ElementType item,int Tag){
  if(PtrS->Top2-PtrS->Top1==1){
    printf("堆疊滿了");
    return;
  }
  if(Tag==1){
    PtrS->Data[++(PtrS->Top1)]=item;
  }
  else{
    PtrS->Data[--(PtrS->Top2)]=item;
  }

}
ElementType Pop(struct DStack* PtrS,int Tag){
if(Tag==1){
    if(PtrS->Top1==-1){
        printf("堆疊1空");
        return NULL;
    }
    else return PtrS->Data[(PtrS->Top1)--];

}else{
  if(PtrS->Top2==MaxSize){
    printf("棧2空");
    return NULL;
  }
  else return PtrS->Data[(PtrS->Top2)++];

}

    

  ②堆疊的鏈式儲存實現

        實際上就是鏈棧:插入和刪除只能在棧頂的棧頂進行。Top應該連結串列的頭上。

#define ElementType int
typedef struct SNode* Stack;
struct SNode{
  ElementType Data;
  struct SNode* Next;
};

  (1)建立空棧

//構造一個堆疊的頭結點,返回指標
Stack CreateStack(){
  Stack S;
  S=(Stack)malloc(sizeof(struct SNode));
  S->Next=NULL;
  return S;
}

  (2)判斷棧頂s是否為空

int IsEmpty(Stack S){
  return S->Next==NULL;
}

  (3)入棧

void Push(ElementType item,Stack S){
   struct SNode* TmpCell;
   TmpCell=(struct SNode*)malloc(sizeof(struct SNode));
   TmpCell->Data=item;
   TmpCell->Next=S->Next;
   S->Next=TmpCell;
 }

  (4)出棧

ElementType Pop(Stack S){
    struct SNode* FirstCell;
    ElementType TopElem;
    if(IsEmpty(S)){
        printf("棧空");
        return NULL;
    }
    else{
        FirstCell=S->Next;
        S->Next=FirstCell->Next;
        TopElem=FirstCell->Data;
        free(FirstCell);
        return TopElem;
    }
}