1. 程式人生 > >資料結構(二)---基本的棧的操作

資料結構(二)---基本的棧的操作

棧的基本操作

在這周自己學了一下簡單的棧的基本操作,對棧有了個基本的瞭解,就比如說,在程式裡記憶體分為靜態記憶體和動態記憶體,這兩者的區別是,靜態記憶體是放在棧裡的,由系統分配記憶體的;動態記憶體是存放在堆裡,由程式設計師手動給的。

棧的本質來講這是一種儲存方式,像是一個“先進後出的箱子”,把資料存放進去,如圖
這裡寫圖片描述
一個bottom一直指這個箱子的最下面的元素(最先放進去的)
一個top一直指著這個箱子的最上面的元素(最後放進去的)
裡面的元素是用連結串列連在一起的
注意:棧裡面最下面的那個元素不放東西,就類似於頭節點

建立資料結構

//這個是資料的資料結構
typedef
struct Node{ int data; struct Node *next; }NODE,*PNODE; //這個是棧的資料結構 typedef struct Stack{ PNODE pTop; //棧頭 PNODE pBottom; //棧底 }STACK,*PSTACK;

初始化棧

就是一開始先定義棧的結構的例項,然後用pBottom和pTop都先指向NULL

void init(PSTACK ps){
    ps->pTop = (PNODE)malloc(sizeof(NODE));
    if(ps->pTop ==
NULL){ printf("動態分配失敗\n"); exit(-1); }else{ ps->pBottom = ps->pTop; ps->pTop->next = NULL; } }

壓棧

void push(PSTACK ps,int val){
    PNODE pNew = (PNODE)malloc(sizeof(NODE));

    pNew->data = val;
    pNew->next = ps->pTop;
    ps->pTop = pNew;
}

出棧

這個出棧的時候,先判斷是否為空,然後把棧頂的節點釋放了,用一個值把它記載下來

bool pop(PSTACK ps,int *pval){
    if(empty(ps)){
        return false;
    }else{
        PNODE r = ps->pTop;
        *pval = r->data;
        ps->pTop = r->next;
        free(r);
        r = NULL;
        return true;
    }
} 

遍歷

不斷從棧頂往下遍歷

void traverse(PSTACK ps){
    PNODE p = ps->pTop;
    while(p!=ps->pBottom){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}

判斷是否為空

當pBottom和pTop相等的時候,就為空

bool empty(PSTACK ps){
    if(ps->pTop == ps->pBottom)
        return true;
    else
        return false;

清空

把裡面的所以節點釋放掉
先判斷是否為空,為空的話,就不用清空了哈

void clear(PSTACK ps){
    if(empty(ps)){
        return;
    } else{
        PNODE p = ps->pTop;
        PNODE q = p->next;

        while(p!=ps->pBottom){
            q = p->next;
            free(p);
            p = q;
        }
        ps->pTop = ps->pBottom;
    }
} 

總的程式碼

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef struct Node{
    int data;
    struct Node *next;
}NODE,*PNODE;

typedef struct Stack{
    PNODE pTop;  //棧頭 
    PNODE pBottom; //棧底 
}STACK,*PSTACK; 

void init(PSTACK);  //初始化棧 
void push(PSTACK,int); //壓棧 
void traverse(PSTACK);  //遍歷
bool pop(PSTACK ps,int *pval); //出棧
bool empty(PSTACK);
void clear(PSTACK);

bool empty(PSTACK ps){
    if(ps->pTop == ps->pBottom)
        return true;
    else
        return false;
} 

bool pop(PSTACK ps,int *pval){
    if(empty(ps)){
        return false;
    }else{
        PNODE r = ps->pTop;
        *pval = r->data;
        ps->pTop = r->next;
        free(r);
        r = NULL;
        return true;
    }
} 
void init(PSTACK ps){
    ps->pTop = (PNODE)malloc(sizeof(NODE));
    if(ps->pTop ==NULL){
        printf("動態分配失敗\n");
        exit(-1); 
    }else{
        ps->pBottom = ps->pTop;
        ps->pTop->next = NULL;
    }
}

void push(PSTACK ps,int val){
    PNODE pNew = (PNODE)malloc(sizeof(NODE));

    pNew->data = val;
    pNew->next = ps->pTop;
    ps->pTop = pNew;
}

void traverse(PSTACK ps){
    PNODE p = ps->pTop;
    while(p!=ps->pBottom){
        printf("%d ",p->data);
        p = p->next;
    }
    printf("\n");
}
void clear(PSTACK ps){
    if(empty(ps)){
        return;
    } else{
        PNODE p = ps->pTop;
        PNODE q = p->next;

        while(p!=ps->pBottom){
            q = p->next;
            free(p);
            p = q;
        }
        ps->pTop = ps->pBottom;
    }
} 
int main(void){
    STACK s;
    int val;
    init(&s);
    push(&s,1);
    push(&s,2);
    push(&s,3);
    if(pop(&s,&val))
    {
        printf("出棧元素是%d\n",val);
    } else{
        printf("失敗\n"); 
    }
    traverse(&s); 
    clear(&s);
    traverse(&s); 
    return 0;
} 

總結

在資料結構的中棧是很重要的一部分,比如函式呼叫,中斷, 表示式求值, 記憶體分配, 緩衝處理, 迷宮 等問題上都會用到棧,這篇部落格只是簡單講下基本棧的操作,以後會繼續研究的哈。