欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

顺序栈与链式栈的实现

程序员文章站 2022-03-12 17:28:58
...

栈的概念:

栈(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);
}

链式栈测试运行结果:

顺序栈与链式栈的实现

图:链式栈测试结果

相关标签: 线性表