• 数据结构与算法实例(栈实现)


    栈是一种应用特别广泛的数据结构,是一种典型的数据结构,实现后悔和回退功能.本实例为:将任意十进制转变为任意进制进行表示。由于进制转换中转换过程中存在取余倒序很好的契合栈"先进后出"的特点,故使用栈存储结构进行实现

    一.栈的定义

    ★栈(stack):只能在一端插入和删除的线性表,又称为“先进后出”的线性表,或“后进先出”的线性表。
    ★栈顶(top):允许进行插入,删除操作的一端,又称为表尾。
    ★栈底(bottom):是固定端,又称为表头。
    ★空栈:当表中没有元素时称空栈。

    二.栈示意图

    三.栈的存储结构

    和线性表类似,栈也有多种存储表示方法
    1.1顺序栈1

    1.2顺序栈2

    2.1链式栈

    四.栈的抽象数据类型

    struct stack *stack_init();//初始化栈存储空间
    void stack_free(struct stack *s);//释放内存空间
    void stack_clear(struct stack *s);//清空内存空间的数据元素
    int stack_isempty(struct stack *s);//判断存储空间的数据元素是否为空
    int stack_count(struct stack *s); //返回栈中数据元素个数
    void stack_push(struct stack *s,int e); //压栈
    int stack_pop(struct stack *s); //将栈中元素弹出来
    int stack_top(struct stack *s); //返回栈顶元素

    五.代码实现

    Stack.h

    #ifndef __STACK_H__
    #define __STACK_H__
    Struct stack;
    
    Struct stack *stack_init();
    Void stack_free(struct stack *s);
    
    Void stack_clear(struct stack *s);
    Int stack_isempty(struct stack *s);
    Int stack_count(struct stack *s);
    
    Void stack_push(struct stack *s,int e);
    Int stack_pop(struct stack *s);
    Int stack_top(struct stack *s);
    
    #endif
    

    Main.c

    //将任意十进制转换为八进制表示
    #include <stdio.h>
    #include <stdlib.h>
    #include "stack.h"
    
    void convert10toD(int n,int d);
    
    int main(int argc, char *argv[]) {
        //定义指针变量s指向stack类型的结构体
        struct stack *s=NULL;
        //初始化栈空间
        s=stack_init();
        //将3/5/6依次入栈
        stack_push(s,3);
        stack_push(s,5);
        stack_push(s,6);
        //栈顶元素
        printf("The top elememnt is %d.
    ",stack_top(s));
        printf("The array isempty %d.
    ",stack_isempty(s));
        //将栈中元素依次取出
        while(!stack_isempty(s)){
           printf("The element is %d.
    ",stack_pop(s));
        }
        stack_free(s);
    
        printf("
    
    ");
        //将10进制数在158装换为8进制
        convert10toD(158,8);
    
        return 0;
    }
    
    void convert10toD(int n,int d)
    {
        struct stack *s=NULL;
        s=stack_init();
    
        int k;
        //逐级取余,依次入栈
        while(n>0){
            k=n%d;
            stack_push(s,k);
            n=n/d;	
        }
        //将栈中元素取出(由于栈"先进后出"的特点完成倒序)
        while(!stack_isempty(s)){
            printf("%d
    ",stack_pop(s));
        }
        stack_free(s);
        return;
    }
    

    Stack.c
    结构①

    //顺序栈
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    #include "stack.h"
    //定义数组初始长度为1,每次增加1
    #define STACK_INIT_SIZE 1
    #define STACK_INCR_SIZE 1
    //定义一级结构,botton用于指向栈底(用来存放数组的首地址),count用来记录栈中数据元素的个数,size用于记录定义栈结构(栈结构中数组)的长度
    struct stack{
        int *bottom;
        int count;
        int size;
    };
    //初始化栈存储结构
    struct stack *stack_init()
    {
        struct stack *s=NULL;
        s=(struct stack *)malloc(sizeof(struct stack));
        if(s==NULL)  return NULL;
    
        assert(s!=NULL);
    
        s->bottom=NULL;
        s->count=0;
        s->size=0;
        s->bottom=(int *)malloc(sizeof(int)*STACK_INIT_SIZE);
        if(s->bottom==NULL){
            free(s);
            return NULL;
        }
        assert(s->bottom!=NULL);
        //将栈中元素清零
        memset(s->bottom,0,sizeof(int)*STACK_INIT_SIZE);
        s->size=STACK_INIT_SIZE;
    
        return s;
    }
    
    void stack_free(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        free(s->bottom);
        free(s);
    }
    
    void stack_clear(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        s->count=0;
    }
    
    int stack_isempty(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        return (s->count==0);
    }
    
    int stack_count(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        return s->count;
    }
    
    void stack_push(struct stack *s,int e)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
        //如果栈空间不够,使用realloc()函数进行扩容操作
        if(s->count==s->size){
            s->bottom=(int *)realloc(s->bottom,sizeof(int)*(s->size+STACK_INCR_SIZE));
            s->size+=STACK_INCR_SIZE;
        }
        
        s->bottom[s->count]=e;
        //每添加一个数据元素,s->count指向新元素后面一个空的位置,方便下次存储  
        s->count++;
    
        return;
    }
    //将栈中数据元素弹出
    int stack_pop(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        int result=-1;
        result=s->bottom[s->count-1];
        s->count--;
    
        return result;
    }
    //取出栈定元素
    int stack_top(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        return s->bottom[s->count-1];
    }
    

    结构②

    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "stack.h"
    
    #define STACK_INIT_SIZE 1
    #define STACK_INCR_SIZE 1
    //定义结构体作为一级结构,bottom指向栈底,top指向栈顶下一个内存空间,size记录定义的栈空间的长度
    struct stack{
        int *bottom;
        int *top;
        int size;
    };
    
    struct stack *stack_init()
    {
        struct stack *s=NULL;
        s=(struct stack *)malloc(sizeof(struct stack));
        if(s==NULL)  return NULL;
    
        assert(s!=NULL);
    
        s->bottom=NULL;
        s->top=NULL;
        s->size=0;
    
        s->bottom=(int *)malloc(sizeof(int)*STACK_INIT_SIZE);
        if(s->bottom==NULL){
            free(s);
            return NULL;
        } 
    
        assert(s->bottom!=NULL);
    
        memset(s->bottom,0,sizeof(int)*STACK_INIT_SIZE);
        s->top=s->bottom;
        s->size=STACK_INIT_SIZE;
    
        return s; 
    }
    
    void stack_free(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s->top!=NULL);
        assert(s!=NULL);
    
        free(s->bottom);
        free(s);
    }
    
    void stack_clear(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
        //让栈顶指针指向栈底实现清除功能
        s->top=s->bottom;
    }
    
    int stack_isempty(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
        
        return (s->top==s->bottom);
    }
    
    int stack_count(struct stack *s)
    {
        ssert(s->bottom!=NULL);
        assert(s!=NULL);
        //栈顶指针减去栈底指针得到栈中有多少个数据元素
        return s->top-s->bottom; 
    }
    
    void stack_push(struct stack *s,int e)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        if((s->top-s->bottom)==s->size){
            s->bottom=(int*)realloc(s->bottom,sizeof(int)*(s->size+STACK_INCR_SIZE));
            s->size+=STACK_INCR_SIZE;
        }
        //添加数据到栈顶
        *(s->top)=e;
        s->top++;
    
        return;
    }
    
    int stack_pop(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        int result=-1;
        result=*(s->top-1);
        s->top--;
    
        return result;
    }
    
    int stack_top(struct stack *s)
    {
        assert(s->bottom!=NULL);
        assert(s!=NULL);
    
        return *(s->top-1);
    }
    

    结构③

    //链式栈
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    #include "stack.h"
    //定义结构体作为数据节点,data用来存放数据,next用来存放下一个数据节点的首地址
    struct stack_node{
        int data;
        struct stack_node *next;
    };
    //定义一级结构,top用来存放数据节点的地址,count用来记录栈结构共包含多少数据节点
    struct stack{
        struct stack_node *top;
        int count;
    };
    
    struct stack *stack_init()
    {
        struct stack *s=NULL;
        s=(struct stack *)malloc(sizeof(struct stack));
        if(s==NULL)   return NULL;
    
        assert(s!=NULL);
    
        s->top=NULL;
        s->count=0;
    
        return s;
    }
    
    void stack_free(struct stack *s)
    {
        assert(s!=NULL);
    
        struct stack_node *p=NULL;
        //逐级将数据节点释放
        while(s&&s->top!=NULL){
            p=s->top;
            p=p->next;
            free(p);
        }
        free(s);
    }
    
    void stack_clear(struct stack *s)
    {
        assert(s!=NULL);
    
        struct stack_node *p=NULL;
    
        while(s&&s->top!=NULL){
            p=s->top;
            s->top=p->next;
            free(p);
        }
        s->count=0;
    }
    
    int stack_isempty(struct stack *s)
    {
        assert(s!=NULL);
    
        return (s->count==0);
    }
    
    int stack_count(struct stack *s)
    {
        assert(s!=NULL);
    
        return s->count;
    }
    
    void stack_push(struct stack *s,int e)
    {
        assert(s!=NULL);
        //定义结构体指针变量node指向stack_node结构体类型的数据
        struct stack_node *node=NULL;
        //node指向新开辟的stack_node结构体类型大小的存储空间
        node=(struct stack_node *)malloc(sizeof(struct stack_node));
        if(node==NULL)  {
            perror("malloc struct error
    ");
            exit(0);
        }
        //将数据元素e赋到结构体中
        node->data=e;
        node->next=NULL;
        //将数据节点添加到链上
        node->next=s->top;
        s->top=node;
        s->count++;
    
        return;
    }
    
    int stack_pop(struct stack *s)
    {
        assert(s!=NULL);
        
        int result=-1;
        struct stack_node *node=NULL;
        //将数据节点断开
        node=s->top;
        s->top=node->next;
        s->count--; 
        //取出数据节点中的数据元素
        result=node->data;
    
        return result;
    }
    
    int stack_top(struct stack *s)
    {
        assert(s!=NULL);
    
        return s->top->data;
    }
    

    六. 编译结果

  • 相关阅读:
    整理了一份FAQ,新手看一下
    分享:pythonbitstring 3.1.2 发布
    分享:TokuDB v7 发布,并宣布全面开源
    在美国学CS能挣多少钱?美国IT公司标准 offer package详细数字及绿卡政策 | 美国留学申请与就业找工作咨询博客|Warald|一亩三分地论坛
    写的split带改进
    分享:一个多进程并发执行程序ps命令 ls命令
    分享:vi/vim使用进阶: 指随意动,移动如飞 (一)
    waning rm i rm rvfi
    分享:C++中头文件、源文件之间的区别与联系
    分享:神奇的动归状态转移方程——最优子序列
  • 原文地址:https://www.cnblogs.com/miaowulj/p/12237920.html
Copyright © 2020-2023  润新知