链式栈(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...
原文地址:https://www.cnblogs.com/Slow-Down/p/13257882.html