zoukankan      html  css  js  c++  java
  • 链式栈(Chain stack)

    线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列。

     规定了某些操作的线性表——栈

    当规定线性表的插入和删除操作都必须在线性表的一个端点进行,而不能在其他的任何位置时,这样的线性表就叫做栈(stack)。

     

     

      1 #ifndef LINKSTACK_H
      2 #define LINKSTACK_H
      3 
      4 #include <stdlib.h>//malloc
      5 #include <stdbool.h>//bool
      6 
      7 //链表节点的数据类型默认是 int
      8 #ifndef LINKSTACK_DATATYPE
      9 #define LINKSTACK_DATATYPE int
     10 #endif
     11 
     12 typedef LINKSTACK_DATATYPE datatype;//取别名
     13 
     14 /*
     15  * 链式栈节点类型
     16  * 即链表节点类型
     17 */
     18 
     19 struct node
     20 {
     21   //数据域
     22   datatype data;
     23   //单链表指针域
     24   struct node *next;
     25 };
     26 
     27 /*
     28  * 链式栈的管理结构体
     29  */
     30 typedef struct
     31 {
     32     //栈顶元素指针
     33     struct node *top;
     34     //链表节点个数
     35     int size;
     36 }linkstack;
     37 
     38 /*
     39  * 初始化链式栈的管理结构体
     40  * 参数:无
     41  * 返回值:
     42  *      成功:返回链式栈的管理结构体指针
     43  *      失败:返回NULL
     44  */
     45 static linkstack *init_linkstack(void)
     46 {
     47     linkstack *ls = malloc(sizeof(linkstack));
     48     if(ls != NULL)
     49     {
     50         //初始时 链式栈的节点个数为0
     51         ls->size = 0;
     52         //初始时 链式栈的栈顶指针指向空
     53         ls->top = NULL;
     54     }
     55     return ls;
     56 }
     57 
     58 /*
     59  * 链式栈的管理结构体
     60  * 参数:
     61  *      man_struct:链式栈的管理结构体指针
     62  * 返回值:
     63  *      链式栈为空:返回true
     64  *      链式栈非空:返回false
     65  */
     66 static bool linkstack_empty(linkstack *man_struct)
     67 {
     68     //栈中节点元素个数为0
     69     return man_struct->size == 0;
     70 }
     71 
     72 
     73 /*
     74  *将新节点入栈
     75  *参数:
     76  *     man_struct:链式栈的管理结构体指针
     77  *     new_node:新节点的指针
     78  * 返回值:无
     79  */
     80 static void linkstack_push(linkstack *man_struct,struct node * new_node)
     81 {
     82     //新节点的指针 指向 原栈顶的节点
     83     new_node->next = man_struct->top;
     84     //更新原栈顶的节点(栈顶指针指向新节点)
     85     man_struct->top = new_node;
     86     //链式栈的元素加1
     87     man_struct->size++;
     88 }
     89 
     90 /*
     91  * 读取栈顶节点的数据域
     92  * 参数:
     93  *     man_struct:链式栈的管理结构体指针
     94  *     save_node:指向栈顶指针的 指针
     95  * 返回值:
     96  *     成功:返回true
     97  *     失败:返回false
     98  */
     99 static bool linkstack_top(linkstack *man_struct,struct node **save_node)
    100 {
    101     //栈空则失败
    102     if(linkstack_empty(man_struct))
    103         return false;
    104 
    105     //为用户提供栈顶节点地址
    106     *save_node = man_struct->top;
    107     return true;
    108 }
    109 
    110 /*
    111  *节点出栈
    112  * 参数:
    113  *      man_struct:链式栈的管理结构体指针
    114  *返回值:
    115  *      成功:返回true
    116  *      失败:返回false(栈空)
    117  */
    118 static bool linkstack_pop(linkstack *man_struct)
    119 {
    120     //栈空就失败
    121     if(linkstack_empty(man_struct))
    122         return false;
    123 
    124     //栈顶节点准备出栈
    125     struct node *p = man_struct->top;
    126 
    127     //管理结构体的栈顶指针指向下面的节点
    128     man_struct->top = man_struct->top->next;
    129     //栈节点的元素减1
    130     man_struct->size--;
    131 
    132     p->next = NULL;//取消指向
    133     free(p);//释放节点
    134     return true;
    135 }
    136 /*
    137  *遍历链式栈 回调 用户实现的访问数据域的函数
    138  * 参数:
    139  *     man_struct:链式栈的管理结构体
    140  *     hander:用户实现的函数 的指针
    141  */
    142 static bool linkstack_travel(linkstack *man_struct,void (*hander)(datatype))
    143 {
    144    //链式栈为空则失败
    145    if(linkstack_empty(man_struct))
    146        return false;
    147 
    148    //记录链式栈节点的指针(过渡使用)
    149    struct node *t = man_struct->top;
    150    while(1)
    151    {
    152        //调用用户实现的访问数据域的函数
    153         hander(t->data);
    154         //下一个节点
    155         t = t->next;
    156 
    157         //如果遍历结束则退出while
    158         if(t == NULL)
    159             break;
    160    }
    161    return true;
    162 }
    163 
    164 /*
    165  * 链式栈回归初始化
    166  * 参数:
    167  *      **man_struct:链式栈的管理结构体指针 的指针
    168  * 返回值:无
    169  */
    170 static void uninit_linkstack(linkstack **man_struct)
    171 {
    172     //从栈顶开始释放节点
    173     struct node *d = (*man_struct)->top;
    174     while(d)//非空
    175     {
    176         //记录下一个节点
    177         struct node *tmp = d->next;
    178         //释放该当前节点
    179         free(d);
    180         //下一个节点
    181         d = tmp;
    182     }
    183     //回归初始化
    184     (*man_struct)->top = NULL;
    185     (*man_struct)->size = 0;
    186 }
    187 
    188 #endif // LINKSTACK_H
     1 /*main.c*/
     2 #include <stdio.h>
     3 
     4 #define LINKSTACK_DATATYPE int
     5 #include "linkstack.h"
     6 
     7 /*
     8  * 申请内存存放新节点
     9  * 参数:
    10  *      data:节点的数据域(根据实际情况)
    11  * 返回值:
    12  *      新节点的地址(堆内存地址)
    13  */
    14 static struct node *new_node(int data)
    15 {
    16     struct node *n = malloc(sizeof(struct node));
    17     if(n != NULL)
    18     {
    19         n->data = data;//数据域
    20         n->next = NULL;//指针域
    21     }
    22     return n;
    23 }
    24 
    25 /*
    26  * 用户实现的访问数据域的函数 回调
    27  * 参数:
    28  *      data:数据
    29  * 返回值:无
    30  */
    31 void show(int data)
    32 {
    33     printf("%d",data);
    34 }
    35 
    36 /*
    37  *主函数
    38  */
    39 int main()
    40 {
    41     //初始化链式栈的管理结构体
    42     linkstack *man_struct = init_linkstack();
    43     if(man_struct == NULL)
    44     {
    45         perror(" ");
    46         return 0;
    47     }
    48 
    49     int num,tmp;
    50 
    51     while(1)
    52     {
    53         printf("输入:");
    54 
    55         if(scanf("%d",&num) !=1)
    56         {
    57             //清空非法输入
    58             while(getchar()!='
    ');
    59             continue;
    60         }
    61 
    62         if(num == -1)//来个结束
    63             return 0;
    64 
    65         while(1)
    66         {
    67             tmp = num/8;//短除法
    68             //余数入栈
    69             linkstack_push(man_struct,new_node(num%8));
    70 
    71             if(tmp == 0)//计算完毕则退出while循环
    72                 break;
    73 
    74             num = tmp;//否者继续
    75         }
    76 
    77         printf("p is :0");
    78         //遍历链式栈(只读)
    79         linkstack_travel(man_struct,show);
    80 
    81         printf("
    ");
    82 
    83         //链式栈的管理结构体回归初始化
    84         uninit_linkstack(&man_struct);
    85     }
    86 
    87     return 0;
    88 }
     1 输入:0
     2 p is :00
     3 输入:8
     4 p is :010
     5 输入:7
     6 p is :07
     7 输入:256256
     8 p is :0764400
     9 输入:-1
    10 Press <RETURN> to close this window...
  • 相关阅读:
    fsockopen
    Ambari安装之部署3个节点的HA分布式集群
    怎么让普通用户达到root用户也可以拥有权限修改文件(CentOS系统)
    谈大数据里各子项目搭建时的环境变量配置(深入)
    Zookeeper的多节点集群详细启动步骤(3或5节点)
    IntelliJ IDEA(Ultimate版本)的下载、安装和WordCount的初步使用(本地模式和集群模式)
    IDEA里如何多种方式打jar包,然后上传到集群
    Zookeeper(1、3、5节点)集群安装
    Hadoop Hive概念学习系列之HDFS、Hive、MySQL、Sqoop之间的数据导入导出(强烈建议去看)
    Hadoop概念学习系列之Java调用Shell命令和脚本,致力于hadoop/spark集群
  • 原文地址:https://www.cnblogs.com/Slow-Down/p/13257882.html
Copyright © 2011-2022 走看看