棧的基本算法


一、簡單介紹
棧是限定進在表尾插入或刪除操作的線性表。因此,對棧來說,表尾端有其特殊的含義,成為棧頂(top),相應地,表頭端稱為棧底(bottom)。

不含元素的空表稱為空棧。棧的修改是按照后進先出的原則進行的,因此,棧又稱為后進先出的線性表。

 

二、棧示意圖

 

三、基本操作

1、棧的初始化: InitStack(&S)
2、棧頂元素插入: Push(&S, &e)
3、棧頂元素獲取: GetTop(&S, &e)
4、棧頂元素刪除: Pop(&S, &e)
5、棧的長度: StackLength(S)
6、棧的判空: StackEmpty(S)
7、棧元素的訪問: StackTraverse(S, visit())
8、棧的清空: ClearStack(&S)
9、棧的銷毀: DestroyStack(&S)

 

四、棧順序存儲的實現

//---------- 棧的順序存儲表示 ---------
#define STACK_INIT_SIZE 100; //存儲空間初始分配量
#define STACKINCREMENT  10;  //存儲空間分配增量
typedef struct {
    SElemType *base; //在棧構造之前和銷毀之后,base的值為NULL
    SElemType *top;  //棧頂指針
    int stacksize;   //當前已分配的存儲空間,以元素為單位 
}SqStack;
//---------- 基本操作的函數原型聲明 --------
Status InitStack(SqStack &S);    //構造一個空棧S
Status DestroyStack(SqStack &S); //銷毀棧S,S不再存在
Status ClearStack(SqStack &S);   //把S置為空棧
Status StackEmpty(SqStack &S);   //若棧S為空棧,則返回TRUE,否則返回FALSE
int StackLength(SqStack &S);     //返回S的元素個數,即棧的長度
Status GetTop(SqStack &S, SElemType &e); //若棧S不空,則用e返回S的棧頂元素,並返回OK,否則返回ERROR
Status Push(SqStack &S, SElemType &e);   //插入元素e為新的棧頂元素
Status Pop(SqStack &S, SElemType &e);    //若棧S不空,則刪除S的棧頂元素e,用e返回其值,返回OK,否則返回ERROR
Status StackTraverse(S, visit(SElemType e));        //從棧頂到棧頂依次對每一個元素調用函數visit()。一旦visit()失敗,則操作失敗
//---------- 基本操作的算法描述 --------
Status InitStack(SqStack &S){
    S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType))
    if(!S.base) exit(OVERFLOW); //存儲分配失敗
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}

Status DestroyStack(SqStack &S){
    free(S.base);
    S.base = NULL;
    S.top = NULL;
    S.stacksize = 0;
    return OK;
}

Status ClearStack(SqStack &S){
    S.top = S.base;
    return OK;
}

Status StackEmpty(SqStack &S){
    if(S.top == S.base) return TRUE;
    return FALSE;
}

int StackLength(SqStack &S){
    return S.top - S.base;
}

Status GetTop(SqStack &S, SElemType &e){
    if(S.top == S.base) return ERROR;
    e = *(S.top - 1);
    return OK;
}

Status Push(SqStack &S, SElemType &e){
    if(S.top - S.base >= S.stacksize){  //棧滿,追加存儲空間
        S.base = (SElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(SElemType));
        if(!S.base) exit(OVERFLOW); //存儲分配失敗
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    * S.top++ = e;
    return OK;
}

Status Pop(SqStack &S, SElemType &e){
    if(S.top == S.base) return ERROR;
    e = * --S.top;
    return OK;
}

Status StackTraverse(S, visit()){
SElemType *base2 = S.base;
while(S.top > S.base2) visit(*S.base2++); return OK; } Status visit(SElemType e) { printf("%d ", e); return OK; }

 

五、代碼實現

//
//  main.c
//  EEs
//
//  Created by 夏遠全 on 2019/9/1.
//  Copyright © 2019 北京一米藍科技有限公司. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <sys/malloc.h>
#include <string.h>
#include <stdio.h>

#define STACK_OVERFLOW   -1
#define STACK_INIT_SIZE 100
#define STACKINCREMENT   10
#define OK               1
#define ERROR            0
#define TRUE             1
#define FALSE            0

typedef int SElemType;
typedef int status;

typedef struct sqstack
{
    SElemType *base;
    SElemType *top;
    int stacksize;
}SqStack;

status Initstack(SqStack *s);
status Destorystack(SqStack *s);
status Clearstack(SqStack *s);
status StackEmpty(SqStack *s);
int StackLength(SqStack *s);
status GetTop(SqStack *s, SElemType *e);
status Push(SqStack *s, SElemType *e);
status Pop(SqStack *s, SElemType *e);
status StackTraverse(SqStack *s, status(*visit)(SElemType e));
status visit(SElemType e);

int main(int argc, const char * argv[]) {

    SElemType i;
    SElemType e = 0;
    SqStack s;
    if(Initstack(&s) == OK){
        for(i = 1; i <= 20; i++){
            Push(&s,&i);
        }
    }
    
    printf("棧中的元素依次為:");
    StackTraverse(&s,visit);
    
    Pop(&s, &e);
    
    GetTop(&s, &e);
    
    StackEmpty(&s);
    
    StackLength(&s);
    
    Clearstack(&s);
    
    StackEmpty(&s);
    
    Destorystack(&s);

    return 0;
}

status Initstack(SqStack *s)
{
    s->base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!s->base) return STACK_OVERFLOW;
    s->top = s->base;
    s->stacksize = STACK_INIT_SIZE;
    return OK;
}

status Push(SqStack *s, SElemType *e)
{
    if (s->top - s->base >= s->stacksize) {  //棧滿 ,追加空間
        s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType));
        if (!s->base) exit(0);
        s->top = s->base + s->stacksize;  // 設置棧頂
        s->stacksize = s->stacksize + STACKINCREMENT;  // 設置棧的最大容量
    }
    *(s->top) = *e;
    s->top ++;
    return OK;
}

status Pop(SqStack *s, SElemType *e)
{
    if(&s->top == &s->base) return ERROR;
    s->top --;
    *e = *(s->top);
    printf("彈出的棧頂元素 e=%d\n", *e);
    return OK;
}

status StackTraverse(SqStack *s, status(*visit)(SElemType e))
{
    SElemType *base2 = s->base;
    while(s->top > base2){
        visit(*(base2++));
    }
    printf("\n");
    return OK;
}

status visit(SElemType e)
{
    printf("%d ", e);
    return OK;
}

status StackEmpty(SqStack *s)
{
    if(s->top == s->base)
    {
        printf("棧的狀態:棧空\n");
        return TRUE;
    }
    else{
        printf("棧的狀態:棧非空\n");
        return FALSE;
    }
}

int StackLength(SqStack *s)
{
    int len = (int)(s->top - s->base);
    printf("棧的長度:len=%d\n", len);
    return 0;
}

status GetTop(SqStack *s, SElemType *e)
{
    if(&s->top == &s->base) return ERROR;
    e = (s->top-1);
    printf("當前棧頂元素:e=%d\n", *e);
    return OK;
}

status Clearstack(SqStack *s)
{
    s->top = s->base;
    return OK;
}

status Destorystack(SqStack *s)
{
    s->base = s->top = NULL;
    s->stacksize = 0;
    free(s->base);
    printf("棧被銷毀:top = %d, base= %d, stacksize = %u\n",s->top,s->base,s->stacksize);
    return OK;
}
View Code

 

六、打印結果

棧中的元素依次為:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
彈出的棧頂元素 e=20
當前棧頂元素:e=19
棧的狀態:棧非空
棧的長度:len=19
棧的狀態:棧空
棧被銷毀:top = 0, base= 0, stacksize = 0
Program ended with exit code: 0

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM