顺序栈与链式栈的实现

栈的概念:

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

顺序栈:

base.h

这个头文件主要用来存放公用的常量和类型。

//base.h
//-----公用的常量和类型----------
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
#include<malloc.h>
#include<string.h>

//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1 //不可行的 infeaslble
#define OVERFLOW -2

typedef int Status;
typedef int SElemType;

sq_Stack.h

sq_Stack.h头文件用来具体实体实现栈的基本操作。

//sq_stack.h  顺序栈

//-------------栈的顺序存储表示----------------

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量

typedef struct{
    SElemType *base; //在栈构造之前和销毁之后,base的值为NULL
    SElemType *top; //栈顶指针
    int stacksize;  //当前分配的存储空间,以元素为单位
}SqStack;

//----基本操作的函数原型说明-----------

//构建一个空栈S
Status InitStack_Sq(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;
}//InitStack_Sq

//销毁栈S
Status DestroyStack_Sq(SqStack &S){
    if(S.base){
        free(S.base);
        S.top = S.base = NULL;
        S.stacksize = 0;
        cout<<"栈销毁成功!"<<endl;
        return OK;
    }else{
        cout<<"栈不存在,不需要销毁!"<<endl;
        return ERROR;
    }
}//DestroyStack_Sq

//初始条件:栈S存在
//操作结果:清空栈
Status CleanStack_Sq(SqStack &S){
    S.top = S.base;
    return OK;
}//CleanStack_Sq

//初始条件:栈S存在
//操作结果:若为空栈,返回TRUE,否则FALSE
Status StackEmpty_Sq(SqStack S){
    if(S.top == S.base){
        cout<<"栈为空!"<<endl;
        return TRUE;
        }
    else{
        cout<<"栈不为空!"<<endl;
        return FALSE;
        }
}//StackEmpty_Sq

//初始条件:栈S存在
//操作结果:返回栈内元素个数,即栈的长度
int StackLength_Sq(SqStack S){
    int len;
    len = (S.top - S.base);
    return len;
}//StackLength_Sq

//初始条件:栈S存在
//操作结果:用e返回S的栈顶元素
Status GetTop_Sq(SqStack S, SElemType &e){
    if(S.top == S.base)//判空
        return ERROR;
    else{
        e = *(S.top - 1);
        return OK;
 }
}//GetTop_Sq

//初始条件:栈S存在
//操作结果:插入元素e为新的栈顶元素
Status Push_Sq(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;
}//Push_Sq

//初始条件:栈S存在
//操作结果:删除S的栈顶元素,并用e返回其值
Status Pop_Sq(SqStack &S, SElemType &e){
    if(S.top == S.base) //判空
        return ERROR;
    e = *--S.top; //返回删除元素的值
    return OK;
}//Pop_Sq

//初始条件:栈S存在
//操作结果:遍历栈元素并显示
Status StackTraverse_Sq(SqStack S){
    if(S.base){  //判断栈是否存在
        if(S.top == S.base) //判空
            cout<<"此栈是个空栈!"<<endl;
        else{
            SElemType *p;
            p = S.top;
            while(p > S.base)
            {
                p--;
                cout<<*p<<"  ";
            }
            cout<<endl;
        }
        return OK;
    }else{
        cout<<"栈不存在!"<<endl;
        return ERROR;
    }

}//StackTraverse_Sq

sqStackText.cpp

用来测试顺序栈的基本操作函数。

#include "base.h"
#include "sq_stack.h"
//用来测试顺序栈的基本操作
int main(){
    SqStack S;
    SElemType e;
    InitStack_Sq(S);
    StackTraverse_Sq(S);
    //给空栈赋值
    for(e = 0; e<10; e++){
        Push_Sq(S, e);
    }
    cout<<"栈的遍历:";
    StackTraverse_Sq(S);
    Push_Sq(S, 15);
    cout<<"压栈15后栈的遍历:";
    StackTraverse_Sq(S);
    Pop_Sq(S, e);
    cout<<"出栈后栈的遍历:";
    StackTraverse_Sq(S);
    cout<<"被删除的元素是:"<<e<<endl;
    GetTop_Sq(S, e);
    cout<<"获取栈顶元素:"<<e<<endl;
    cout<<"栈的长度为(即栈内元素个数):"
                <<StackLength_Sq(S)<<endl;
    cout<<"判栈空:";
    StackEmpty_Sq(S);
    cout<<"清空栈!"<<endl;
    CleanStack_Sq(S);
    cout<<"判栈空:";
    StackEmpty_Sq(S);
    cout<<"销毁栈:";
    DestroyStack_Sq(S);
    cout<<"再次销毁栈:";
    DestroyStack_Sq(S);
    return OK;
}

程序运行结果:

这里写图片描述

图:顺序栈测试的运行结果

链式栈:

link_stack.h

链式表的具体代码实现:

//link_stack.h  链式栈

//-------------栈的链式存储表示----------------

#define STACK_INIT_SIZE 100 //存储空间初始分配量
#define STACKINCREMENT 10 //存储空间分配增量

typedef struct StackNode{
    SElemType date; //数据域
    struct StackNode *next;
}StackNode, *LinkStackPtr;

typedef struct LinkStack{
    LinkStackPtr top; //栈顶
    int count; //记录栈元素个数
}*PLinkStack;
//----基本操作的函数原型说明-----------

//构建一个空栈S
Status InitStack_L(PLinkStack* S){
    //分配一个节点的初始化空间
    *S = (PLinkStack)malloc(sizeof(struct LinkStack));
    (*S)->top = NULL; //栈顶指针指向空
    (*S)->count = 0; //栈中元素个数初始为0
    return OK;
}//InitStack_L

//初始条件:栈S存在
//操作结果:清空栈
Status CleanStack_L(PLinkStack &S){
    LinkStackPtr p;
     //栈不为空时,进行循环,释放每一个节点的空间
    while(S->top){
        p = S->top;
        S->top = S->top->next;
        S->count--;
        free(p);
    }
    return OK;
}//CleanStack_L

//销毁栈S
Status DestroyStack_L(PLinkStack* S){
    CleanStack_L(*S); //先清空栈
    free(*S); //释放栈所有空间
    cout<<"栈销毁成功!"<<endl;
    return OK;
}//DestroyStack_L

//初始条件:栈S存在
//操作结果:若为空栈,返回TRUE,否则FALSE
Status StackEmpty_L(PLinkStack S){
    if(S->top){  //栈顶存在
        cout<<"栈不为空!"<<endl;
        return TRUE;
    }else{
        cout<<"栈为空!"<<endl;
        return FALSE;
    }
}//StackEmpty_L

//初始条件:栈S存在
//操作结果:返回栈内元素个数,即栈的长度
int StackLength_L(PLinkStack S){
    return S->count;
}//StackLength_L

//初始条件:栈S存在
//操作结果:用e返回S的栈顶元素
Status GetTop_L(PLinkStack S, SElemType &e){
    if(!S->top)
        return ERROR;
    e = S->top->date;
    return OK;
}//GetTop_L

//初始条件:栈S存在
//操作结果:插入元素e为新的栈顶元素
Status Push_L(PLinkStack &S, SElemType e){
    LinkStackPtr p = (LinkStackPtr)malloc(sizeof(struct StackNode));
    p->date = e;
    p->next = S->top;
    S->top = p;
    S->count++;
    return OK;
}//Push_L

//初始条件:栈S存在
//操作结果:删除S的栈顶元素,并用e返回其值
Status Pop_L(PLinkStack &S, SElemType &e){
   LinkStackPtr p;
   if(!S->top){
        return ERROR;
   }
   e = S->top->date;
   p = S->top;
   S->top = S->top->next;
   S->count--;
   free(p);
   return OK;
}//Pop_L

//初始条件:栈S存在
//操作结果:遍历栈元素并显示
Status StackTraverse_L(PLinkStack S){
    if(S->top){
        LinkStackPtr p;
        p = S->top;
        while(p){
            cout<<p->date<<"  ";
            p = p->next;
        }
        cout<<endl;
        return OK;
    }else{
        cout<<"此栈为空栈!"<<endl;
        return OK;
    }
}//StackTraverse_L

linkStackText

链式栈的测试:

void linkStackText(){
    PLinkStack S;
    SElemType e;
    InitStack_L(&S);
    StackTraverse_L(S);
    //给空栈赋值
    for(e = 0; e<10; e++){
        Push_L(S, e);
    }
    cout<<"栈的遍历:";
    StackTraverse_L(S);
    Push_L(S, 15);
    cout<<"压栈15后栈的遍历:";
    StackTraverse_L(S);
    Pop_L(S, e);
    cout<<"出栈后栈的遍历:";
    StackTraverse_L(S);
    cout<<"被删除的元素是:"<<e<<endl;
    GetTop_L(S, e);
    cout<<"获取栈顶元素:"<<e<<endl;
    cout<<"栈的长度为(即栈内元素个数):"
                <<StackLength_L(S)<<endl;
    cout<<"判栈空:";
    StackEmpty_L(S);
    cout<<"清空栈!"<<endl;
    CleanStack_L(S);
    cout<<"栈的遍历:";
    StackTraverse_L(S);
    cout<<"判栈空:";
    StackEmpty_L(S);
    cout<<"销毁栈:";
    DestroyStack_L(&S);
}

链式栈测试运行结果:

这里写图片描述

图:链式栈测试结果

猜你喜欢

转载自blog.csdn.net/qq_38265137/article/details/78321028