栈_java实现_栈的图文解析 和 对应3种语言的实现(C/C++/Java)

概要

本章会先对栈的原理进行介绍,然后分别通过C/C++/Java三种语言来演示栈的实现示例。注意:本文所说的栈是数据结构中的栈,而不是内存模型中栈。内容包括:

栈的介绍

栈(stack),是一种线性存储结构,它有以下几个特点:

(01) 栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的。

(02) 向栈中添加/删除数据时,只能从栈顶进行操作。

栈通常包括的三种操作:push、peek、pop。

push -- 向栈中添加元素。

peek -- 返回栈顶元素。

pop  -- 返回并删除栈顶元素的操作。

1. 栈的示意图

18178a3414e5cf3f6add9fe098982676.png

栈中的数据依次是 30 --> 20 --> 10

2. 出栈

b8ae819638a73f9321692392c870a3f3.png

出栈前:栈顶元素是30。此时,栈中的元素依次是 30 --> 20 --> 10

出栈后:30出栈之后,栈顶元素变成20。此时,栈中的元素依次是 20 --> 10

3. 入栈

b11bc3e9b0f7f9b70d3916e66e9fcf40.png

入栈前:栈顶元素是20。此时,栈中的元素依次是 20 --> 10

入栈后:40入栈之后,栈顶元素变成40。此时,栈中的元素依次是 40 --> 20 --> 10

下面介绍栈的实现,分别介绍C/C++/Java三种实现。

栈的C实现

共介绍4种C语言实现。

1. C语言实现一:数组实现的栈,并且只能存储int数据。

2. C语言实现二:单向链表实现的栈,并且只能存储int数据。

3. C语言实现三:双向链表实现的栈,并且只能存储int数据。

4. C语言实现四:双向链表实现的栈,能存储任意类型的数据。

1. C语言实现一:数组实现的栈,并且只能存储int数据

实现代码(array_stack.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3

4 /**5 * C 语言: 数组实现的栈,只能存储int数据。6 *7 * @author skywang8 * @date 2013/11/079 */

10

11 //保存数据的数组

12 static int *arr=NULL;13 //栈的实际大小

14 static intcount;15

16 //创建“栈”,默认大小是12

17 int create_array_stack(intsz)18 {19 arr = (int *)malloc(sz*sizeof(int));20 if (!arr)21 {22 printf("arr malloc error!");23 return -1;24 }25

26 return 0;27 }28

29 //销毁“栈”

30 intdestroy_array_stack()31 {32 if(arr)33 {34 free(arr);35 arr =NULL;36 }37

38 return 0;39 }40

41 //将val添加到栈中

42 void push(intval)43 {44 arr[count++] =val;45 }46

47 //返回“栈顶元素值”

48 intpeek()49 {50 return arr[count-1];51 }52

53 //返回“栈顶元素值”,并删除“栈顶元素”

54 intpop()55 {56 int ret = arr[count-1];57 count--;58 returnret;59 }60

61 //返回“栈”的大小

62 intsize()63 {64 returncount;65 }66

67 //返回“栈”是否为空

68 intis_empty()69 {70 return size()==0;71 }72

73 //打印“栈”

74 voidprint_array_stack()75 {76 if(is_empty())77 {78 printf("stack is Empty\n");79 return;80 }81

82 printf("stack size()=%d\n", size());83

84 int i=size()-1;85 while (i>=0)86 {87 printf("%d\n", arr[i]);88 i--;89 }90 }91

92

93 voidmain()94 {95 int tmp=0;96

97 //创建“栈”

98 create_array_stack(12);99

100 //将10, 20, 30 依次推入栈中

101 push(10);102 push(20);103 push(30);104

105 //print_array_stack();//打印栈106

107 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

108 tmp =pop();109 printf("tmp=%d\n", tmp);110 //print_array_stack();//打印栈111

112 //只将“栈顶”赋值给tmp,不删除该元素.

113 tmp =peek();114 printf("tmp=%d\n", tmp);115 //print_array_stack();//打印栈

116

117 push(40);118 print_array_stack(); //打印栈119

120 //销毁栈

121 destroy_array_stack();122 }

View Code

运行结果:

tmp=30tmp=20stack size()=3

40

20

10

结果说明:该示例中的栈,是通过"数组"来实现的!

由于代码中已经给出了详细了注释,这里就不再对函数进行说明了。仅对主函数main的逻辑进行简单介绍。

(01) 在主函数main中,先将 "10, 20, 30"依次压入栈。此时,栈的数据是: 30 --> 20 --> 10

(02) 接着通过pop()返回栈顶元素;pop()操作并不会改变栈中的数据。此时,栈的数据依然是: 30 --> 20 --> 10

(03) 接着通过peek()返回并删除栈顶元素。peek操作之后,栈的数据是: 20 --> 10

(04) 接着通过push(40)将40压入栈中。push(40)操作之后,栈的数据是: 40 --> 20 --> 10

2. C语言实现二:单向链表实现的栈,并且只能存储int数据

实现代码(slink_stack.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3

4 /**5 * C 语言: 单向链表实现的栈,只能存储int数据。6 *7 * @author skywang8 * @date 2013/11/079 */

10

11 //单向链表的“节点”

12 structnode {13 intval;14 struct node*next;15 };16

17 //单向链表的“表头”

18 static struct node *phead=NULL;19

20 //创建节点,val为节点值

21 static struct node* create_node(intval)22 {23 struct node *pnode=NULL;24 pnode = (struct node*)malloc(sizeof(structnode));25 if (!pnode)26 returnNULL;27 pnode->val =val;28 pnode->next =NULL;29

30 returnpnode;31 }32

33 //销毁单向链表

34 static intdestroy_single_link()35 {36 struct node *pnode=NULL;37

38 while (phead !=NULL) {39 pnode =phead;40 phead = phead->next;41 free(pnode);42 }43 return 0;44 }45

46 //将val插入到链表的表头位置

47 static struct node* push(intval)48 {49 struct node *pnode =NULL;50

51 pnode =create_node(val);52 pnode->next =phead;53 phead =pnode;54

55 returnphead;56 }57

58 //删除链表的表头

59 static intpop()60 {61 if (!phead)62 {63 printf("remove failed! link is empty!");64 return -1;65 }66

67 intret;68 struct node *pnode;69 ret = phead->val;70 pnode =phead;71 phead = phead->next;72 free(pnode);73

74 returnret;75 }76

77 //返回链表的表头节点的值

78 static intpeek()79 {80 if (!phead)81 {82 printf("peek failed! link is empty!");83 return -1;84 }85

86 return phead->val;87 }88

89 //返回链表中节点的个数

90 static intsize()91 {92 int count=0;93 struct node *pnode=phead;94

95 while (pnode !=NULL) {96 pnode = pnode->next;97 count++;98 }99 returncount;100 }101

102 //链表是否为空

103 static intis_empty()104 {105 return phead==NULL;106 }107

108 //打印“栈”

109 static voidprint_single_link()110 {111 if(is_empty())112 {113 printf("stack is Empty\n");114 return 0;115 }116

117 printf("stack size()=%d\n", size());118

119 struct node *pnode=NULL;120

121 while (phead !=NULL) {122 printf("%d\n", phead->val);123 pnode =phead;124 phead = phead->next;125 free(pnode);126 }127 }128

129 voidmain()130 {131 int tmp=0;132

133 //将10, 20, 30 依次推入栈中

134 push(10);135 push(20);136 push(30);137

138 //print_single_link();//打印栈139

140 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

141 tmp =pop();142 printf("tmp=%d\n", tmp);143 //print_single_link();//打印栈144

145 //只将“栈顶”赋值给tmp,不删除该元素.

146 tmp =peek();147 printf("tmp=%d\n", tmp);148 //print_single_link();//打印栈

149

150 push(40);151 print_single_link(); //打印栈152

153 //销毁栈

154 destroy_single_link();155 }

View Code

代码说明:"运行结果" 以及 "主函数main的逻辑"都和"C语言实现一"的一样。不同的是,该示例中的栈是通过单向链表实现的。

3. C语言实现三:双向链表实现的栈,并且只能存储int数据

实现代码

双向链表的头文件(double_link.h)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #ifndef _DOUBLE_LINK_H2 #define _DOUBLE_LINK_H

3

4 //新建“双向链表”。成功,返回表头;否则,返回NULL

5 extern intcreate_dlink();6 //撤销“双向链表”。成功,返回0;否则,返回-1

7 extern intdestroy_dlink();8

9 //“双向链表是否为空”。为空的话返回1;否则,返回0。

10 extern intdlink_is_empty();11 //返回“双向链表的大小”

12 extern intdlink_size();13

14 //获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。

15 extern int dlink_get(intindex);16 //获取“双向链表中第1个元素的值”。成功,返回节点值;否则,返回-1。

17 extern intdlink_get_first();18 //获取“双向链表中最后1个元素的值”。成功,返回节点值;否则,返回-1。

19 extern intdlink_get_last();20

21 //将“value”插入到index位置。成功,返回0;否则,返回-1。

22 extern int dlink_insert(int index, intvalue);23 //将“value”插入到表头位置。成功,返回0;否则,返回-1。

24 extern int dlink_insert_first(intvalue);25 //将“value”插入到末尾位置。成功,返回0;否则,返回-1。

26 extern int dlink_append_last(intvalue);27

28 //删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1

29 extern int dlink_delete(intindex);30 //删除第一个节点。成功,返回0;否则,返回-1

31 extern intdlink_delete_first();32 //删除组后一个节点。成功,返回0;否则,返回-1

33 extern intdlink_delete_last();34

35 //打印“双向链表”

36 extern voidprint_dlink();37

38 #endif

View Code

双向链表的实现文件double_link.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3

4 /**5 * c语言实现的双向链表6 *7 * @author skywang8 * @date 2013/11/079 */

10 //双向链表节点

11 typedef structtag_node12 {13 struct tag_node *prev;14 struct tag_node *next;15 intvalue;16 }node;17

18 //表头。注意,表头不存放元素值!!!

19 static node *phead=NULL;20 //节点个数。

21 static int count=0;22

23 //新建“节点”。成功,返回节点指针;否则,返回NULL。

24 static node* create_node(intvalue)25 {26 node *pnode=NULL;27 pnode = (node *)malloc(sizeof(node));28 if (!pnode)29 {30 printf("create node error!\n");31 returnNULL;32 }33 //默认的,pnode的前一节点和后一节点都指向它自身

34 pnode->prev = pnode->next =pnode;35 //节点的值为value

36 pnode->value =value;37

38 returnpnode;39 }40

41 //新建“双向链表”。成功,返回0;否则,返回-1。

42 intcreate_dlink()43 {44 //创建表头

45 phead = create_node(-1);46 if (!phead)47 return -1;48

49 //设置“节点个数”为0

50 count = 0;51

52 return 0;53 }54

55 //“双向链表是否为空”

56 intdlink_is_empty()57 {58 return count == 0;59 }60

61 //返回“双向链表的大小”

62 intdlink_size() {63 returncount;64 }65

66 //获取“双向链表中第index位置的节点”

67 static node* get_node(intindex)68 {69 if (index<0 || index>=count)70 {71 printf("%s failed! the index in out of bound!\n", __func__);72 returnNULL;73 }74

75 //正向查找

76 if (index <= (count/2))77 {78 int i=0;79 node *pnode=phead->next;80 while ((i++) next;82

83 //printf("%s %d i=%d, pnode->value=%d\n",84 //__func__, __LINE__, i, pnode->value);

85 returnpnode;86 }87

88 //反向查找

89 int j=0;90 int rindex = count - index - 1;91 node *rnode=phead->prev;92 while ((j++) prev;94

95 //printf("%s %d j=%d, rnode->value=%d\n",96 //__func__, __LINE__, j, rnode->value);

97 returnrnode;98 }99

100 //获取“第一个节点”

101 static node*get_first_node()102 {103 return get_node(0);104 }105

106 //获取“最后一个节点”

107 static node*get_last_node()108 {109 return get_node(count-1);110 }111

112 //获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。

113 int dlink_get(intindex)114 {115 node *pindex=get_node(index);116 if (!pindex)117 {118 printf("%s failed!\n", __func__);119 return -1;120 }121

122 return pindex->value;123

124 }125

126 //获取“双向链表中第1个元素的值”

127 intdlink_get_first()128 {129 return dlink_get(0);130 }131

132 //获取“双向链表中最后1个元素的值”

133 intdlink_get_last()134 {135 return dlink_get(count-1);136 }137

138 //将“value”插入到index位置。成功,返回0;否则,返回-1。

139 int dlink_insert(int index, intvalue)140 {141 //插入表头

142 if (index==0)143 returndlink_insert_first(value);144

145 //获取要插入的位置对应的节点

146 node *pindex=get_node(index);147 if (!pindex)148 return -1;149

150 //创建“节点”

151 node *pnode=create_node(value);152 if (!pnode)153 return -1;154

155 pnode->prev = pindex->prev;156 pnode->next =pindex;157 pindex->prev->next =pnode;158 pindex->prev =pnode;159 //节点个数+1

160 count++;161

162 return 0;163 }164

165 //将“value”插入到表头位置

166 int dlink_insert_first(intvalue)167 {168 node *pnode=create_node(value);169 if (!pnode)170 return -1;171

172 pnode->prev =phead;173 pnode->next = phead->next;174 phead->next->prev =pnode;175 phead->next =pnode;176 count++;177 return 0;178 }179

180 //将“value”插入到末尾位置

181 int dlink_append_last(intvalue)182 {183 node *pnode=create_node(value);184 if (!pnode)185 return -1;186

187 pnode->next =phead;188 pnode->prev = phead->prev;189 phead->prev->next =pnode;190 phead->prev =pnode;191 count++;192 return 0;193 }194

195 //删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。

196 int dlink_delete(intindex)197 {198 node *pindex=get_node(index);199 if (!pindex)200 {201 printf("%s failed! the index in out of bound!\n", __func__);202 return -1;203 }204

205 pindex->next->prev = pindex->prev;206 pindex->prev->next = pindex->next;207 free(pindex);208 count--;209

210 return 0;211 }212

213 //删除第一个节点

214 intdlink_delete_first()215 {216 return dlink_delete(0);217 }218

219 //删除组后一个节点

220 intdlink_delete_last()221 {222 return dlink_delete(count-1);223 }224

225 //撤销“双向链表”。成功,返回0;否则,返回-1。

226 intdestroy_dlink()227 {228 if (!phead)229 {230 printf("%s failed! dlink is null!\n", __func__);231 return -1;232 }233

234 node *pnode=phead->next;235 node *ptmp=NULL;236 while(pnode !=phead)237 {238 ptmp =pnode;239 pnode = pnode->next;240 free(ptmp);241 }242

243 free(phead);244 phead =NULL;245 count = 0;246

247 return 0;248 }249

250 //打印“双向链表”

251 voidprint_dlink()252 {253 if (count==0 || (!phead))254 {255 printf("stack is Empty\n");256 return;257 }258

259 printf("stack size()=%d\n", count);260 node *pnode=phead->next;261 while(pnode !=phead)262 {263 printf("%d\n", pnode->value);264 pnode = pnode->next;265 }266 }

View Code

双向链表的测试程序(dlink_stack.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include "double_link.h"

3

4 /**5 * C 语言: 双向链表实现栈,只能存储int数据。6 *7 * @author skywang8 * @date 2013/11/079 */

10 //创建栈

11 intcreate_dlink_stack()12 {13 returncreate_dlink();14 }15

16 //销毁栈

17 intdestroy_dlink_stack()18 {19 returndestroy_dlink();20 }21

22 //将val添加到栈中

23 int push(intval)24 {25 returndlink_insert_first(val);26 }27

28 //返回“栈顶元素值”

29 intpeek()30 {31 returndlink_get_first();32 }33

34 //返回“栈顶元素值”,并删除“栈顶元素”

35 intpop()36 {37 int ret =peek();38 dlink_delete_first();39 returnret;40 }41

42 //返回“栈”的大小

43 intsize()44 {45 returndlink_size();46 }47

48 //返回“栈”是否为空

49 intis_empty()50 {51 returndlink_is_empty();52 }53

54 //打印“栈”

55 voidprint_dlink_stack()56 {57 returnprint_dlink();58 }59

60 voidmain()61 {62 int tmp=0;63

64 //创建“栈”

65 create_dlink_stack();66

67 //将10, 20, 30 依次推入栈中

68 push(10);69 push(20);70 push(30);71

72 //print_dlink_stack();//打印栈73

74 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

75 tmp =pop();76 printf("tmp=%d\n", tmp);77 //print_dlink_stack();//打印栈78

79 //只将“栈顶”赋值给tmp,不删除该元素.

80 tmp =peek();81 printf("tmp=%d\n", tmp);82 //print_dlink_stack();//打印栈

83

84 push(40);85 print_dlink_stack(); //打印栈86

87 //销毁栈

88 destroy_dlink_stack();89 }

View Code

代码说明:"运行结果" 以及 "主函数main的逻辑"都和前两个示例的一样。不同的是,该示例中的栈是通过双向链表实现的。

4. C语言实现四:双向链表实现的栈,能存储任意类型的数据

实现代码

双向链表的头文件(double_link.h)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #ifndef _DOUBLE_LINK_H2 #define _DOUBLE_LINK_H

3

4 //新建“双向链表”。成功,返回表头;否则,返回NULL

5 extern intcreate_dlink();6 //撤销“双向链表”。成功,返回0;否则,返回-1

7 extern intdestroy_dlink();8

9 //“双向链表是否为空”。为空的话返回1;否则,返回0。

10 extern intdlink_is_empty();11 //返回“双向链表的大小”

12 extern intdlink_size();13

14 //获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。

15 extern void* dlink_get(intindex);16 //获取“双向链表中第1个元素”。成功,返回节点指针;否则,返回NULL。

17 extern void*dlink_get_first();18 //获取“双向链表中最后1个元素”。成功,返回节点指针;否则,返回NULL。

19 extern void*dlink_get_last();20

21 //将“value”插入到index位置。成功,返回0;否则,返回-1。

22 extern int dlink_insert(int index, void *pval);23 //将“value”插入到表头位置。成功,返回0;否则,返回-1。

24 extern int dlink_insert_first(void *pval);25 //将“value”插入到末尾位置。成功,返回0;否则,返回-1。

26 extern int dlink_append_last(void *pval);27

28 //删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1

29 extern int dlink_delete(intindex);30 //删除第一个节点。成功,返回0;否则,返回-1

31 extern intdlink_delete_first();32 //删除组后一个节点。成功,返回0;否则,返回-1

33 extern intdlink_delete_last();34

35 #endif

View Code

双向链表的实现文件(double_link.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3

4

5 /**6 * C 语言实现的双向链表,能存储任意数据。7 *8 * @author skywang9 * @date 2013/11/0710 */

11 //双向链表节点

12 typedef structtag_node13 {14 struct tag_node *prev;15 struct tag_node *next;16 void*p;17 }node;18

19 //表头。注意,表头不存放元素值!!!

20 static node *phead=NULL;21 //节点个数。

22 static int count=0;23

24 //新建“节点”。成功,返回节点指针;否则,返回NULL。

25 static node* create_node(void *pval)26 {27 node *pnode=NULL;28 pnode = (node *)malloc(sizeof(node));29 if (!pnode)30 {31 printf("create node error!\n");32 returnNULL;33 }34 //默认的,pnode的前一节点和后一节点都指向它自身

35 pnode->prev = pnode->next =pnode;36 //节点的值为pval

37 pnode->p =pval;38

39 returnpnode;40 }41

42 //新建“双向链表”。成功,返回0;否则,返回-1。

43 intcreate_dlink()44 {45 //创建表头

46 phead =create_node(NULL);47 if (!phead)48 return -1;49

50 //设置“节点个数”为0

51 count = 0;52

53 return 0;54 }55

56 //“双向链表是否为空”

57 intdlink_is_empty()58 {59 return count == 0;60 }61

62 //返回“双向链表的大小”

63 intdlink_size() {64 returncount;65 }66

67 //获取“双向链表中第index位置的节点”

68 static node* get_node(intindex)69 {70 if (index<0 || index>=count)71 {72 printf("%s failed! index out of bound!\n", __func__);73 returnNULL;74 }75

76 //正向查找

77 if (index <= (count/2))78 {79 int i=0;80 node *pnode=phead->next;81 while ((i++) next;83

84 returnpnode;85 }86

87 //反向查找

88 int j=0;89 int rindex = count - index - 1;90 node *rnode=phead->prev;91 while ((j++) prev;93

94 returnrnode;95 }96

97 //获取“第一个节点”

98 static node*get_first_node()99 {100 return get_node(0);101 }102

103 //获取“最后一个节点”

104 static node*get_last_node()105 {106 return get_node(count-1);107 }108

109 //获取“双向链表中第index位置的元素”。成功,返回节点值;否则,返回-1。

110 void* dlink_get(intindex)111 {112 node *pindex=get_node(index);113 if (!pindex)114 {115 printf("%s failed!\n", __func__);116 returnNULL;117 }118

119 return pindex->p;120

121 }122

123 //获取“双向链表中第1个元素的值”

124 void*dlink_get_first()125 {126 return dlink_get(0);127 }128

129 //获取“双向链表中最后1个元素的值”

130 void*dlink_get_last()131 {132 return dlink_get(count-1);133 }134

135 //将“pval”插入到index位置。成功,返回0;否则,返回-1。

136 int dlink_insert(int index, void*pval)137 {138 //插入表头

139 if (index==0)140 returndlink_insert_first(pval);141

142 //获取要插入的位置对应的节点

143 node *pindex=get_node(index);144 if (!pindex)145 return -1;146

147 //创建“节点”

148 node *pnode=create_node(pval);149 if (!pnode)150 return -1;151

152 pnode->prev = pindex->prev;153 pnode->next =pindex;154 pindex->prev->next =pnode;155 pindex->prev =pnode;156 //节点个数+1

157 count++;158

159 return 0;160 }161

162 //将“pval”插入到表头位置

163 int dlink_insert_first(void *pval)164 {165 node *pnode=create_node(pval);166 if (!pnode)167 return -1;168

169 pnode->prev =phead;170 pnode->next = phead->next;171 phead->next->prev =pnode;172 phead->next =pnode;173 count++;174 return 0;175 }176

177 //将“pval”插入到末尾位置

178 int dlink_append_last(void *pval)179 {180 node *pnode=create_node(pval);181 if (!pnode)182 return -1;183

184 pnode->next =phead;185 pnode->prev = phead->prev;186 phead->prev->next =pnode;187 phead->prev =pnode;188 count++;189 return 0;190 }191

192 //删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。

193 int dlink_delete(intindex)194 {195 node *pindex=get_node(index);196 if (!pindex)197 {198 printf("%s failed! the index in out of bound!\n", __func__);199 return -1;200 }201

202 pindex->next->prev = pindex->prev;203 pindex->prev->next = pindex->next;204 free(pindex);205 count--;206

207 return 0;208 }209

210 //删除第一个节点

211 intdlink_delete_first()212 {213 return dlink_delete(0);214 }215

216 //删除组后一个节点

217 intdlink_delete_last()218 {219 return dlink_delete(count-1);220 }221

222 //撤销“双向链表”。成功,返回0;否则,返回-1。

223 intdestroy_dlink()224 {225 if (!phead)226 {227 printf("%s failed! dlink is null!\n", __func__);228 return -1;229 }230

231 node *pnode=phead->next;232 node *ptmp=NULL;233 while(pnode !=phead)234 {235 ptmp =pnode;236 pnode = pnode->next;237 free(ptmp);238 }239

240 free(phead);241 phead =NULL;242 count = 0;243

244 return 0;245 }

View Code

双向链表的测试程序(dlink_stack.c)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include "double_link.h"

3

4 /**5 * C 语言: 双向链表实现栈,能存储任意数据。6 *7 * @author skywang8 * @date 2013/11/079 */

10 //创建栈

11 intcreate_dlink_stack()12 {13 returncreate_dlink();14 }15

16 //销毁栈

17 intdestroy_dlink_stack()18 {19 returndestroy_dlink();20 }21

22 //将val添加到栈中

23 int push(void *p)24 {25 returndlink_insert_first(p);26 }27

28 //返回“栈顶元素值”

29 void*peek()30 {31 returndlink_get_first();32 }33

34 //返回“栈顶元素值”,并删除“栈顶元素”

35 void*pop()36 {37 void *p =peek();38 dlink_delete_first();39 returnp;40 }41

42 //返回“栈”的大小

43 intsize()44 {45 returndlink_size();46 }47

48 //返回“栈”是否为空

49 intis_empty()50 {51 returndlink_is_empty();52 }53

54

55 typedef structtag_stu56 {57 intid;58 char name[20];59 }stu;60

61 static stu arr_stu[] =

62 {63 {10, "sky"},64 {20, "jody"},65 {30, "vic"},66 {40, "dan"},67 };68 #define ARR_STU_SIZE ( (sizeof(arr_stu)) / (sizeof(arr_stu[0])) )

69

70 static void print_stu(stu *p)71 {72 if (!p)73 return;74

75 printf("id=%d, name=%s\n", p->id, p->name);76 }77

78 voidmain()79 {80 stu *pval=NULL;81

82 //创建“栈”

83 create_dlink_stack();84

85 //将10, 20, 30 依次推入栈中

86 int i=0;87 for (i=0; i

92 //将“栈顶元素”赋值给pval,并删除“栈顶元素”

93 pval = (stu*)pop();94 //print_stu(pval) ;95

96 //只将“栈顶”赋值给pval,不删除该元素.

97 pval =peek();98 //print_stu(pval) ;

99

100 push(&arr_stu[ARR_STU_SIZE-1]);101

102

103 //打印栈中的所有元素

104 while (!is_empty())105 {106 pval =pop();107 print_stu(pval) ;108 }109

110 //销毁栈

111 destroy_dlink_stack();112 }

View Code

运行结果:

id=40, name=dan

id=20, name=jody

id=10, name=sky

结果说明:该示例中的栈是通过双向链表实现的,并且能存储任意类型的数据。示例中是以结构体类型的数据进行演示的,由于代码中已经给出了详细的注释,这里就不再介绍了。

栈的C++实现

C++的STL中本身就包含了stack类,基本上该stack类就能满足我们的需求,所以很少需要我们自己来实现。本部分介绍2种C++实现。

1. C++实现一:数组实现的栈,能存储任意类型的数据。

2. C++实现二:C++的 STL 中自带的"栈"(stack)的示例。

1. C++实现一:数组实现的栈,能存储任意类型的数据

实现代码

栈的实现文件(ArrayStack.h)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #ifndef ARRAY_STACK_HXX2 #define ARRAY_STACK_HXX

3

4 #include

5 #include "ArrayStack.h"

6 using namespacestd;7

8 template classArrayStack{9 public:10 ArrayStack();11 ~ArrayStack();12

13 voidpush(T t);14 T peek();15 T pop();16 intsize();17 intisEmpty();18 private:19 T *arr;20 intcount;21 };22

23 //创建“栈”,默认大小是12

24 template

25 ArrayStack::ArrayStack()26 {27 arr = new T[12];28 if (!arr)29 {30 cout<

34 //销毁“栈”

35 template

36 ArrayStack::~ArrayStack()37 {38 if(arr)39 {40 delete[] arr;41 arr =NULL;42 }43 }44

45 //将val添加到栈中

46 template

47 void ArrayStack::push(T t)48 {49 //arr[count++] = val;

50 arr[count++] =t;51 }52

53 //返回“栈顶元素值”

54 template

55 T ArrayStack::peek()56 {57 return arr[count-1];58 }59

60 //返回“栈顶元素值”,并删除“栈顶元素”

61 template

62 T ArrayStack::pop()63 {64 int ret = arr[count-1];65 count--;66 returnret;67 }68

69 //返回“栈”的大小

70 template

71 int ArrayStack::size()72 {73 returncount;74 }75

76 //返回“栈”是否为空

77 template

78 int ArrayStack::isEmpty()79 {80 return size()==0;81 }82

83 #endif

View Code

栈的测试程序(Main.cpp)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include "ArrayStack.h"

3 using namespacestd;4

5 intmain()6 {7 int tmp=0;8 ArrayStack *astack = new ArrayStack();9

10 cout<

12 //将10, 20, 30 依次推入栈中

13 astack->push(10);14 astack->push(20);15 astack->push(30);16

17 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

18 tmp = astack->pop();19 cout<

21 //只将“栈顶”赋值给tmp,不删除该元素.

22 tmp = astack->peek();23

24 astack->push(40);25

26 while (!astack->isEmpty())27 {28 tmp = astack->pop();29 cout<

32 return 0;33 }

View Code

运行结果:

main

tmp=30

40

20

10

结果说明:关于"栈的声明和实现都在头文件中"的原因,是因为栈的实现利用了C++模板,而"C++编译器不能支持对模板的分离式编译"。这在"数据结构和算法01之 线性表"中已经介绍过了。程序的实现和逻辑都非常简单。需要说明的是,采用C++模板实现的;但是,默认数组的大小只有12,而且该实现不支持动态扩展。

2. C++实现二:C++的 STL 中自带的"栈"(stack)的示例

实现代码(StlStack.cpp)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 #include

2 #include

3 using namespacestd;4

5 /**6 * C++ 语言: STL 自带的“栈”(stack)的示例。7 *8 * @author skywang9 * @date 2013/11/0710 */

11 intmain ()12 {13 int tmp=0;14 stackistack;15

16 //将10, 20, 30 依次推入栈中

17 istack.push(10);18 istack.push(20);19 istack.push(30);20

21 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

22 istack.pop();23

24 //只将“栈顶”赋值给tmp,不删除该元素.

25 tmp =istack.top();26

27 istack.push(40);28

29 while (!istack.empty())30 {31 tmp =istack.top();32 istack.pop();33 cout<

36 return 0;37 }

View Code

运行结果:

40

20

10

栈的Java实现

和C++一样,JDK包中也提供了"栈"的实现,它就是集合框架中的Stack类。关于Stack类的原理,在"Java 集合系列07之 Stack详细介绍(源码解析)和使用示例"中,已经详细介绍过了。本部分给出2种Java实现

Java实现一:数组实现的栈,能存储任意类型的数据。

Java实现二:Java的 Collection集合 中自带的"栈"(stack)的示例。

1. Java实现一:数组实现的栈,能存储任意类型的数据

实现代码(GeneralArrayStack.java)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 /**

2 * Java : 数组实现的栈,能存储任意类型的数据3 *4 *@authorskywang5 * @date 2013/11/076 */

7 importjava.lang.reflect.Array;8

9 public class GeneralArrayStack{10

11 private static final int DEFAULT_SIZE = 12;12 privateT[] mArray;13 private intcount;14

15 public GeneralArrayStack(Classtype) {16 this(type, DEFAULT_SIZE);17 }18

19 public GeneralArrayStack(Class type, intsize) {20 //不能直接使用mArray = new T[DEFAULT_SIZE];

21 mArray =(T[]) Array.newInstance(type, size);22 count = 0;23 }24

25 //将val添加到栈中

26 public voidpush(T val) {27 mArray[count++] =val;28 }29

30 //返回“栈顶元素值”

31 publicT peek() {32 return mArray[count-1];33 }34

35 //返回“栈顶元素值”,并删除“栈顶元素”

36 publicT pop() {37 T ret = mArray[count-1];38 count--;39 returnret;40 }41

42 //返回“栈”的大小

43 public intsize() {44 returncount;45 }46

47 //返回“栈”是否为空

48 public booleanisEmpty() {49 return size()==0;50 }51

52 //打印“栈”

53 public voidPrintArrayStack() {54 if(isEmpty()) {55 System.out.printf("stack is Empty\n");56 }57

58 System.out.printf("stack size()=%d\n", size());59

60 int i=size()-1;61 while (i>=0) {62 System.out.println(mArray[i]);63 i--;64 }65 }66

67 public static voidmain(String[] args) {68 String tmp;69 GeneralArrayStack astack = new GeneralArrayStack(String.class);70

71 //将10, 20, 30 依次推入栈中

72 astack.push("10");73 astack.push("20");74 astack.push("30");75

76 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

77 tmp =astack.pop();78 System.out.println("tmp="+tmp);79

80 //只将“栈顶”赋值给tmp,不删除该元素.

81 tmp =astack.peek();82 System.out.println("tmp="+tmp);83

84 astack.push("40");85 astack.PrintArrayStack(); //打印栈

86 }87 }

View Code

运行结果:

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 tmp=30

2 tmp=20

3 stack size()=3

4 40

5 20

6 10

View Code

结果说明:GeneralArrayStack是通过数组实现的栈,而且GeneralArrayStack中使用到了泛型。

2. Java实现二:Java的 Collection集合 中自带的"栈"(stack)的示例

实现代码(StackTest.java)

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 importjava.util.Stack;2

3 /**

4 * Java : java集合包中的Stack的演示程序5 *6 *@authorskywang7 * @date 2013/11/078 */

9 public classStackTest {10

11 public static voidmain(String[] args) {12 int tmp=0;13 Stack astack = new Stack();14

15 //将10, 20, 30 依次推入栈中

16 astack.push(10);17 astack.push(20);18 astack.push(30);19

20 //将“栈顶元素”赋值给tmp,并删除“栈顶元素”

21 tmp =astack.pop();22 //System.out.printf("tmp=%d\n", tmp);23

24 //只将“栈顶”赋值给tmp,不删除该元素.

25 tmp = (int)astack.peek();26 //System.out.printf("tmp=%d\n", tmp);

27

28 astack.push(40);29 while(!astack.empty()) {30 tmp = (int)astack.pop();31 System.out.printf("tmp=%d\n", tmp);32 }33 }34 }

View Code

运行结果:

tmp=40tmp=20tmp=10

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值