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

来源:互联网 发布:zip解压软件mac版 编辑:程序博客网 时间:2024/05/15 23:44

出自:http://www.cnblogs.com/skywang12345/p/3562239.html

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

 

概要

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

转载请注明出处:http://www.cnblogs.com/skywang12345/p/3562239.html


更多内容: 数据结构与算法系列 目录

 

栈的介绍

栈(stack),是一种线性存储结构,它有以下几个特点:
(01) 栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的。
(02) 向栈中添加/删除数据时,只能从栈顶进行操作。

栈通常包括的三种操作:pushpeekpop
push -- 向栈中添加元素。
peek -- 返回栈顶元素。
pop  -- 返回并删除栈顶元素的操作。

 

1. 栈的示意图

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

 

2. 出栈

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

 

3. 入栈

入栈前:栈顶元素是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)

复制代码
  1 #include <stdio.h>  2 #include <malloc.h>  3   4 /**  5  * C 语言: 数组实现的栈,只能存储int数据。  6  *  7  * @author skywang  8  * @date 2013/11/07  9  */ 10  11 // 保存数据的数组 12 static int *arr=NULL; 13 // 栈的实际大小 14 static int count; 15  16 // 创建“栈”,默认大小是12 17 int create_array_stack(int sz)  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 int destroy_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(int val)  43 { 44     arr[count++] = val; 45 } 46  47 // 返回“栈顶元素值” 48 int peek()  49 { 50     return arr[count-1]; 51 } 52  53 // 返回“栈顶元素值”,并删除“栈顶元素” 54 int pop()  55 { 56     int ret = arr[count-1]; 57     count--; 58     return ret; 59 } 60  61 // 返回“栈”的大小 62 int size()  63 { 64     return count; 65 } 66  67 // 返回“栈”是否为空 68 int is_empty() 69 { 70     return size()==0; 71 } 72  73 // 打印“栈” 74 void print_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 void main()  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 }
复制代码

运行结果

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

结果说明该示例中的栈,是通过"数组"来实现的!
由于代码中已经给出了详细了注释,这里就不再对函数进行说明了。仅对主函数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)

复制代码
  1 #include <stdio.h>  2 #include <malloc.h>  3   4 /**  5  * C 语言: 单向链表实现的栈,只能存储int数据。  6  *  7  * @author skywang  8  * @date 2013/11/07  9  */ 10  11 // 单向链表的“节点” 12 struct node { 13     int val; 14     struct node* next; 15 }; 16  17 // 单向链表的“表头” 18 static struct node *phead=NULL; 19  20 // 创建节点,val为节点值 21 static struct node* create_node(int val)  22 { 23     struct node *pnode=NULL; 24     pnode = (struct node*)malloc(sizeof(struct node)); 25     if (!pnode) 26         return NULL; 27     pnode->val = val; 28     pnode->next = NULL; 29      30     return pnode; 31 } 32  33 // 销毁单向链表 34 static int destroy_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(int val)  48 { 49     struct node *pnode = NULL; 50      51     pnode = create_node(val); 52     pnode->next = phead; 53     phead = pnode; 54      55     return phead; 56 } 57  58 // 删除链表的表头 59 static int pop()  60 { 61     if (!phead) 62     { 63         printf("remove failed! link is empty!"); 64         return -1; 65     } 66      67     int ret; 68     struct node *pnode; 69     ret = phead->val; 70     pnode = phead; 71     phead = phead->next; 72     free(pnode); 73  74     return ret; 75 } 76  77 // 返回链表的表头节点的值 78 static int peek()  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 int size()  91 { 92     int count=0; 93     struct node *pnode=phead; 94  95     while (pnode != NULL) { 96         pnode = pnode->next; 97         count++; 98     } 99     return count;100 }101 102 // 链表是否为空103 static int is_empty() 104 {105     return phead==NULL;106 }107 108 // 打印“栈”109 static void print_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 void main() 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 }
复制代码

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

 

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

实现代码
双向链表的头文件(double_link.h)

复制代码
 1 #ifndef _DOUBLE_LINK_H 2 #define _DOUBLE_LINK_H 3  4 // 新建“双向链表”。成功,返回表头;否则,返回NULL 5 extern int create_dlink(); 6 // 撤销“双向链表”。成功,返回0;否则,返回-1 7 extern int destroy_dlink(); 8  9 // “双向链表是否为空”。为空的话返回1;否则,返回0。10 extern int dlink_is_empty();11 // 返回“双向链表的大小”12 extern int dlink_size();13 14 // 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。15 extern int dlink_get(int index);16 // 获取“双向链表中第1个元素的值”。成功,返回节点值;否则,返回-1。17 extern int dlink_get_first();18 // 获取“双向链表中最后1个元素的值”。成功,返回节点值;否则,返回-1。19 extern int dlink_get_last();20 21 // 将“value”插入到index位置。成功,返回0;否则,返回-1。22 extern int dlink_insert(int index, int value);23 // 将“value”插入到表头位置。成功,返回0;否则,返回-1。24 extern int dlink_insert_first(int value);25 // 将“value”插入到末尾位置。成功,返回0;否则,返回-1。26 extern int dlink_append_last(int value);27 28 // 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-129 extern int dlink_delete(int index);30 // 删除第一个节点。成功,返回0;否则,返回-131 extern int dlink_delete_first();32 // 删除组后一个节点。成功,返回0;否则,返回-133 extern int dlink_delete_last();34 35 // 打印“双向链表”36 extern void print_dlink();37 38 #endif 
复制代码

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

复制代码
  1 #include <stdio.h>  2 #include <malloc.h>  3   4 /**  5  * c语言实现的双向链表  6  *  7  * @author skywang  8  * @date   2013/11/07  9  */ 10 // 双向链表节点 11 typedef struct tag_node  12 { 13     struct tag_node *prev; 14     struct tag_node *next; 15     int value; 16 }node; 17  18 // 表头。注意,表头不存放元素值!!! 19 static node *phead=NULL; 20 // 节点个数。 21 static int  count=0; 22  23 // 新建“节点”。成功,返回节点指针;否则,返回NULL。 24 static node* create_node(int value) 25 { 26     node *pnode=NULL; 27     pnode = (node *)malloc(sizeof(node)); 28     if (!pnode) 29     { 30         printf("create node error!\n"); 31         return NULL; 32     } 33     // 默认的,pnode的前一节点和后一节点都指向它自身 34     pnode->prev = pnode->next = pnode; 35     // 节点的值为value 36     pnode->value = value; 37  38     return pnode; 39 } 40  41 // 新建“双向链表”。成功,返回0;否则,返回-1。 42 int create_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 int dlink_is_empty() 57 { 58     return count == 0; 59 } 60  61 // 返回“双向链表的大小” 62 int dlink_size() { 63     return count; 64 } 65  66 // 获取“双向链表中第index位置的节点” 67 static node* get_node(int index)  68 { 69     if (index<0 || index>=count) 70     { 71         printf("%s failed! the index in out of bound!\n", __func__); 72         return NULL; 73     } 74  75     // 正向查找 76     if (index <= (count/2)) 77     { 78         int i=0; 79         node *pnode=phead->next; 80         while ((i++) < index)  81             pnode = pnode->next; 82  83 //        printf("%s %d i=%d, pnode->value=%d\n",  84 //                __func__, __LINE__, i, pnode->value); 85         return pnode; 86     } 87  88     // 反向查找 89     int j=0; 90     int rindex = count - index - 1; 91     node *rnode=phead->prev; 92     while ((j++) < rindex)  93         rnode = rnode->prev; 94  95 //    printf("%s %d j=%d, rnode->value=%d\n",  96 //            __func__, __LINE__, j, rnode->value); 97     return rnode; 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(int index)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 int dlink_get_first()128 {129     return dlink_get(0);130 }131 132 // 获取“双向链表中最后1个元素的值”133 int dlink_get_last()134 {135     return dlink_get(count-1);136 }137 138 // 将“value”插入到index位置。成功,返回0;否则,返回-1。139 int dlink_insert(int index, int value) 140 {141     // 插入表头142     if (index==0)143         return dlink_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     // 节点个数+1160     count++;161 162     return 0;163 }164 165 // 将“value”插入到表头位置166 int dlink_insert_first(int value) 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(int value) 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(int index)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 int dlink_delete_first() 215 {216     return dlink_delete(0);217 }218 219 // 删除组后一个节点220 int dlink_delete_last() 221 {222     return dlink_delete(count-1);223 }224 225 // 撤销“双向链表”。成功,返回0;否则,返回-1。226 int destroy_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 void print_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 }
复制代码

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

复制代码
 1 #include <stdio.h> 2 #include "double_link.h" 3  4 /** 5  * C 语言: 双向链表实现栈,只能存储int数据。 6  * 7  * @author skywang 8  * @date 2013/11/07 9  */10 // 创建栈11 int create_dlink_stack() 12 {13     return create_dlink();14 }15 16 // 销毁栈17 int destroy_dlink_stack() 18 {19     return destroy_dlink();20 }21 22 // 将val添加到栈中23 int push(int val) 24 {25     return dlink_insert_first(val);26 }27 28 // 返回“栈顶元素值”29 int peek() 30 {31     return dlink_get_first();32 }33 34 // 返回“栈顶元素值”,并删除“栈顶元素”35 int pop() 36 {37     int ret = peek();38     dlink_delete_first();39     return ret;40 }41 42 // 返回“栈”的大小43 int size() 44 {45     return dlink_size();46 }47 48 // 返回“栈”是否为空49 int is_empty()50 {51     return dlink_is_empty();52 }53 54 // 打印“栈”55 void print_dlink_stack()56 {57     return print_dlink();58 }59 60 void main()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 }
复制代码

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

 

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

实现代码
双向链表的头文件(double_link.h)

复制代码
 1 #ifndef _DOUBLE_LINK_H 2 #define _DOUBLE_LINK_H 3  4 // 新建“双向链表”。成功,返回表头;否则,返回NULL 5 extern int create_dlink(); 6 // 撤销“双向链表”。成功,返回0;否则,返回-1 7 extern int destroy_dlink(); 8  9 // “双向链表是否为空”。为空的话返回1;否则,返回0。10 extern int dlink_is_empty();11 // 返回“双向链表的大小”12 extern int dlink_size();13 14 // 获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。15 extern void* dlink_get(int index);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;否则,返回-129 extern int dlink_delete(int index);30 // 删除第一个节点。成功,返回0;否则,返回-131 extern int dlink_delete_first();32 // 删除组后一个节点。成功,返回0;否则,返回-133 extern int dlink_delete_last();34 35 #endif 
复制代码

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

复制代码
  1 #include <stdio.h>  2 #include <malloc.h>  3   4   5 /**  6  * C 语言实现的双向链表,能存储任意数据。  7  *  8  * @author skywang  9  * @date 2013/11/07 10  */ 11 // 双向链表节点 12 typedef struct tag_node  13 { 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         return NULL; 33     } 34     // 默认的,pnode的前一节点和后一节点都指向它自身 35     pnode->prev = pnode->next = pnode; 36     // 节点的值为pval 37     pnode->p = pval; 38  39     return pnode; 40 } 41  42 // 新建“双向链表”。成功,返回0;否则,返回-1。 43 int create_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 int dlink_is_empty() 58 { 59     return count == 0; 60 } 61  62 // 返回“双向链表的大小” 63 int dlink_size() { 64     return count; 65 } 66  67 // 获取“双向链表中第index位置的节点” 68 static node* get_node(int index)  69 { 70     if (index<0 || index>=count) 71     { 72         printf("%s failed! index out of bound!\n", __func__); 73         return NULL; 74     } 75  76     // 正向查找 77     if (index <= (count/2)) 78     { 79         int i=0; 80         node *pnode=phead->next; 81         while ((i++) < index)  82             pnode = pnode->next; 83  84         return pnode; 85     } 86  87     // 反向查找 88     int j=0; 89     int rindex = count - index - 1; 90     node *rnode=phead->prev; 91     while ((j++) < rindex)  92         rnode = rnode->prev; 93  94     return rnode; 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(int index)111 {112     node *pindex=get_node(index);113     if (!pindex) 114     {115         printf("%s failed!\n", __func__);116         return NULL;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         return dlink_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     // 节点个数+1157     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(int index)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 int dlink_delete_first() 212 {213     return dlink_delete(0);214 }215 216 // 删除组后一个节点217 int dlink_delete_last() 218 {219     return dlink_delete(count-1);220 }221 222 // 撤销“双向链表”。成功,返回0;否则,返回-1。223 int destroy_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 }
复制代码

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

复制代码
  1 #include <stdio.h>  2 #include "double_link.h"  3   4 /**  5  * C 语言: 双向链表实现栈,能存储任意数据。  6  *  7  * @author skywang  8  * @date 2013/11/07  9  */ 10 // 创建栈 11 int create_dlink_stack()  12 { 13     return create_dlink(); 14 } 15  16 // 销毁栈 17 int destroy_dlink_stack()  18 { 19     return destroy_dlink(); 20 } 21  22 // 将val添加到栈中 23 int push(void *p)  24 { 25     return dlink_insert_first(p); 26 } 27  28 // 返回“栈顶元素值” 29 void* peek()  30 { 31     return dlink_get_first(); 32 } 33  34 // 返回“栈顶元素值”,并删除“栈顶元素” 35 void* pop()  36 { 37     void *p = peek(); 38     dlink_delete_first(); 39     return p; 40 } 41  42 // 返回“栈”的大小 43 int size()  44 { 45     return dlink_size(); 46 } 47  48 // 返回“栈”是否为空 49 int is_empty() 50 { 51     return dlink_is_empty(); 52 } 53  54  55 typedef struct tag_stu 56 { 57     int id; 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 void main() 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<ARR_STU_SIZE-1; i++) 88     { 89         push(&arr_stu[i]); 90     } 91  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 }
复制代码

运行结果

id=40, name=danid=20, name=jodyid=10, name=sky

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

 

栈的C++实现

C++的STL中本身就包含了stack类,基本上该stack类就能满足我们的需求,所以很少需要我们自己来实现。本部分介绍2种C++实现。
1. C++实现一:数组实现的栈,能存储任意类型的数据。
2. C++实现二:C++的 STL 中自带的"栈"(stack)的示例。

 

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

实现代码
栈的实现文件(ArrayStack.h)

复制代码
 1 #ifndef ARRAY_STACK_HXX 2 #define ARRAY_STACK_HXX 3  4 #include <iostream> 5 #include "ArrayStack.h" 6 using namespace std; 7  8 template<class T> class ArrayStack{ 9     public:10         ArrayStack();11         ~ArrayStack();12 13         void push(T t);14         T peek();15         T pop();16         int size();17         int isEmpty();18     private:19         T *arr;20         int count;21 };22 23 // 创建“栈”,默认大小是1224 template<class T>25 ArrayStack<T>::ArrayStack() 26 {27     arr = new T[12];28     if (!arr) 29     {30         cout<<"arr malloc error!"<<endl;31     }32 }33 34 // 销毁“栈”35 template<class T>36 ArrayStack<T>::~ArrayStack() 37 {38     if (arr) 39     {40         delete[] arr;41         arr = NULL;42     }43 }44 45 // 将val添加到栈中46 template<class T>47 void ArrayStack<T>::push(T t) 48 {49     //arr[count++] = val;50     arr[count++] = t;51 }52 53 // 返回“栈顶元素值”54 template<class T>55 T ArrayStack<T>::peek() 56 {57     return arr[count-1];58 }59 60 // 返回“栈顶元素值”,并删除“栈顶元素”61 template<class T>62 T ArrayStack<T>::pop() 63 {64     int ret = arr[count-1];65     count--;66     return ret;67 }68 69 // 返回“栈”的大小70 template<class T>71 int ArrayStack<T>::size() 72 {73     return count;74 }75 76 // 返回“栈”是否为空77 template<class T>78 int ArrayStack<T>::isEmpty()79 {80     return size()==0;81 }82 83 #endif
复制代码

栈的测试程序(Main.cpp)

复制代码
 1 #include <iostream> 2 #include "ArrayStack.h" 3 using namespace std; 4  5 int main()  6 { 7     int tmp=0; 8     ArrayStack<int> *astack = new ArrayStack<int>(); 9 10     cout<<"main"<<endl;11 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<<"tmp="<<tmp<<endl;20 21     // 只将“栈顶”赋值给tmp,不删除该元素.22     tmp = astack->peek();23 24     astack->push(40);25 26     while (!astack->isEmpty())27     {28         tmp = astack->pop();29         cout<<tmp<<endl;30     }31 32     return 0;33 }
复制代码

运行结果

maintmp=30402010

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

 

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

实现代码(StlStack.cpp)

复制代码
 1 #include <iostream> 2 #include <stack> 3 using namespace std; 4  5 /** 6  * C++ 语言: STL 自带的“栈”(stack)的示例。 7  * 8  * @author skywang 9  * @date 2013/11/0710  */11 int main ()12 {13     int tmp=0;14     stack<int> istack;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<<tmp<<endl;34     }35 36     return 0;37 }
复制代码

运行结果

402010

 


0 0
原创粉丝点击