栈的介绍

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

栈通常包括的三种操作:push、peek、pop。
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)

#include <stdio.h>
#include <malloc.h>/*** C 语言: 数组实现的栈,只能存储int数据。** @author skywang* @date 2013/11/07*/// 保存数据的数组
static int *arr=NULL;
// 栈的实际大小
static int count;// 创建“栈”,默认大小是12
int create_array_stack(int sz)
{arr = (int *)malloc(sz*sizeof(int));if (!arr) {printf("arr malloc error!");return -1;}return 0;
}// 销毁“栈”
int destroy_array_stack()
{if (arr) {free(arr);arr = NULL;}return 0;
}// 将val添加到栈中
void push(int val)
{arr[count++] = val;
}// 返回“栈顶元素值”
int peek()
{return arr[count-1];
}// 返回“栈顶元素值”,并删除“栈顶元素”
int pop()
{int ret = arr[count-1];count--;return ret;
}// 返回“栈”的大小
int size()
{return count;
}// 返回“栈”是否为空
int is_empty()
{return size()==0;
}// 打印“栈”
void print_array_stack()
{if (is_empty()) {printf("stack is Empty\n");return ;}printf("stack size()=%d\n", size());int i=size()-1;while (i>=0){printf("%d\n", arr[i]);i--;}
}void main()
{int tmp=0;// 创建“栈”create_array_stack(12);// 将10, 20, 30 依次推入栈中push(10);push(20);push(30);//print_array_stack();    // 打印栈// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = pop();printf("tmp=%d\n", tmp);//print_array_stack();    // 打印栈// 只将“栈顶”赋值给tmp,不删除该元素.tmp = peek();printf("tmp=%d\n", tmp);//print_array_stack();    // 打印栈push(40);print_array_stack();    // 打印栈// 销毁栈destroy_array_stack();
}

运行结果:

tmp=30
tmp=20
stack 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)

#include <stdio.h>
#include <malloc.h>/*** C 语言: 单向链表实现的栈,只能存储int数据。** @author skywang* @date 2013/11/07*/// 单向链表的“节点”
struct node {int val;struct node* next;
};// 单向链表的“表头”
static struct node *phead=NULL;// 创建节点,val为节点值
static struct node* create_node(int val)
{struct node *pnode=NULL;pnode = (struct node*)malloc(sizeof(struct node));if (!pnode)return NULL;pnode->val = val;pnode->next = NULL;return pnode;
}// 销毁单向链表
static int destroy_single_link()
{struct node *pnode=NULL;while (phead != NULL) {pnode = phead;phead = phead->next;free(pnode);}return 0;
}// 将val插入到链表的表头位置
static struct node* push(int val)
{struct node *pnode = NULL;pnode = create_node(val);pnode->next = phead;phead = pnode;return phead;
}// 删除链表的表头
static int pop()
{if (!phead){printf("remove failed! link is empty!");return -1;}int ret;struct node *pnode;ret = phead->val;pnode = phead;phead = phead->next;free(pnode);return ret;
}// 返回链表的表头节点的值
static int peek()
{if (!phead){printf("peek failed! link is empty!");return -1;}return phead->val;
}// 返回链表中节点的个数
static int size()
{int count=0;struct node *pnode=phead;while (pnode != NULL) {pnode = pnode->next;count++;}return count;
}// 链表是否为空
static int is_empty()
{return phead==NULL;
}// 打印“栈”
static void print_single_link()
{if (is_empty()) {printf("stack is Empty\n");return 0;}printf("stack size()=%d\n", size());struct node *pnode=NULL;while (phead != NULL) {printf("%d\n", phead->val);pnode = phead;phead = phead->next;free(pnode);}
}void main()
{int tmp=0;// 将10, 20, 30 依次推入栈中push(10);push(20);push(30);//print_single_link();    // 打印栈// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = pop();printf("tmp=%d\n", tmp);//print_single_link();    // 打印栈// 只将“栈顶”赋值给tmp,不删除该元素.tmp = peek();printf("tmp=%d\n", tmp);//print_single_link();    // 打印栈push(40);print_single_link();    // 打印栈// 销毁栈destroy_single_link();
}

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

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

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

#ifndef _DOUBLE_LINK_H
#define _DOUBLE_LINK_H// 新建“双向链表”。成功,返回表头;否则,返回NULL
extern int create_dlink();
// 撤销“双向链表”。成功,返回0;否则,返回-1
extern int destroy_dlink();// “双向链表是否为空”。为空的话返回1;否则,返回0。
extern int dlink_is_empty();
// 返回“双向链表的大小”
extern int dlink_size();// 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get(int index);
// 获取“双向链表中第1个元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get_first();
// 获取“双向链表中最后1个元素的值”。成功,返回节点值;否则,返回-1。
extern int dlink_get_last();// 将“value”插入到index位置。成功,返回0;否则,返回-1。
extern int dlink_insert(int index, int value);
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
extern int dlink_insert_first(int value);
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
extern int dlink_append_last(int value);// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
extern int dlink_delete(int index);
// 删除第一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_first();
// 删除组后一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_last();// 打印“双向链表”
extern void print_dlink();#endif

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

#include <stdio.h>
#include <malloc.h>/*** c语言实现的双向链表** @author skywang* @date   2013/11/07*/
// 双向链表节点
typedef struct tag_node
{struct tag_node *prev;struct tag_node *next;int value;
}node;// 表头。注意,表头不存放元素值!!!
static node *phead=NULL;
// 节点个数。
static int  count=0;// 新建“节点”。成功,返回节点指针;否则,返回NULL。
static node* create_node(int value)
{node *pnode=NULL;pnode = (node *)malloc(sizeof(node));if (!pnode){printf("create node error!\n");return NULL;}// 默认的,pnode的前一节点和后一节点都指向它自身pnode->prev = pnode->next = pnode;// 节点的值为valuepnode->value = value;return pnode;
}// 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{// 创建表头phead = create_node(-1);if (!phead)return -1;// 设置“节点个数”为0count = 0;return 0;
}// “双向链表是否为空”
int dlink_is_empty()
{return count == 0;
}// 返回“双向链表的大小”
int dlink_size() {return count;
}// 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{if (index<0 || index>=count){printf("%s failed! the index in out of bound!\n", __func__);return NULL;}// 正向查找if (index <= (count/2)){int i=0;node *pnode=phead->next;while ((i++) < index) pnode = pnode->next;//        printf("%s %d i=%d, pnode->value=%d\n",
//                __func__, __LINE__, i, pnode->value);return pnode;}// 反向查找int j=0;int rindex = count - index - 1;node *rnode=phead->prev;while ((j++) < rindex) rnode = rnode->prev;//    printf("%s %d j=%d, rnode->value=%d\n",
//            __func__, __LINE__, j, rnode->value);return rnode;
}// 获取“第一个节点”
static node* get_first_node()
{return get_node(0);
}// 获取“最后一个节点”
static node* get_last_node()
{return get_node(count-1);
}// 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。
int dlink_get(int index)
{node *pindex=get_node(index);if (!pindex) {printf("%s failed!\n", __func__);return -1;}return pindex->value;}// 获取“双向链表中第1个元素的值”
int dlink_get_first()
{return dlink_get(0);
}// 获取“双向链表中最后1个元素的值”
int dlink_get_last()
{return dlink_get(count-1);
}// 将“value”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, int value)
{// 插入表头if (index==0)return dlink_insert_first(value);// 获取要插入的位置对应的节点node *pindex=get_node(index);if (!pindex) return -1;// 创建“节点”node *pnode=create_node(value);if (!pnode)return -1;pnode->prev = pindex->prev;pnode->next = pindex;pindex->prev->next = pnode;pindex->prev = pnode;// 节点个数+1count++;return 0;
}// 将“value”插入到表头位置
int dlink_insert_first(int value)
{node *pnode=create_node(value);if (!pnode)return -1;pnode->prev = phead;pnode->next = phead->next;phead->next->prev = pnode;phead->next = pnode;count++;return 0;
}// 将“value”插入到末尾位置
int dlink_append_last(int value)
{node *pnode=create_node(value);if (!pnode)return -1;pnode->next = phead;pnode->prev = phead->prev;phead->prev->next = pnode;phead->prev = pnode;count++;return 0;
}// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。
int dlink_delete(int index)
{node *pindex=get_node(index);if (!pindex) {printf("%s failed! the index in out of bound!\n", __func__);return -1;}pindex->next->prev = pindex->prev;pindex->prev->next = pindex->next;free(pindex);count--;return 0;
}    // 删除第一个节点
int dlink_delete_first()
{return dlink_delete(0);
}// 删除组后一个节点
int dlink_delete_last()
{return dlink_delete(count-1);
}// 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{if (!phead){printf("%s failed! dlink is null!\n", __func__);return -1;}node *pnode=phead->next;node *ptmp=NULL;while(pnode != phead){ptmp = pnode;pnode = pnode->next;free(ptmp);}free(phead);phead = NULL;count = 0;return 0;
}// 打印“双向链表”
void print_dlink()
{if (count==0 || (!phead)){printf("stack is Empty\n");return ;}printf("stack size()=%d\n", count);node *pnode=phead->next;while(pnode != phead){printf("%d\n", pnode->value);pnode = pnode->next;}
}

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

#include <stdio.h>
#include "double_link.h"/*** C 语言: 双向链表实现栈,只能存储int数据。** @author skywang* @date 2013/11/07*/
// 创建栈
int create_dlink_stack()
{return create_dlink();
}// 销毁栈
int destroy_dlink_stack()
{return destroy_dlink();
}// 将val添加到栈中
int push(int val)
{return dlink_insert_first(val);
}// 返回“栈顶元素值”
int peek()
{return dlink_get_first();
}// 返回“栈顶元素值”,并删除“栈顶元素”
int pop()
{int ret = peek();dlink_delete_first();return ret;
}// 返回“栈”的大小
int size()
{return dlink_size();
}// 返回“栈”是否为空
int is_empty()
{return dlink_is_empty();
}// 打印“栈”
void print_dlink_stack()
{return print_dlink();
}void main()
{int tmp=0;// 创建“栈”create_dlink_stack();// 将10, 20, 30 依次推入栈中push(10);push(20);push(30);//print_dlink_stack();    // 打印栈// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = pop();printf("tmp=%d\n", tmp);//print_dlink_stack();    // 打印栈// 只将“栈顶”赋值给tmp,不删除该元素.tmp = peek();printf("tmp=%d\n", tmp);//print_dlink_stack();    // 打印栈push(40);print_dlink_stack();    // 打印栈// 销毁栈destroy_dlink_stack();
}

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

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

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

#ifndef _DOUBLE_LINK_H
#define _DOUBLE_LINK_H// 新建“双向链表”。成功,返回表头;否则,返回NULL
extern int create_dlink();
// 撤销“双向链表”。成功,返回0;否则,返回-1
extern int destroy_dlink();// “双向链表是否为空”。为空的话返回1;否则,返回0。
extern int dlink_is_empty();
// 返回“双向链表的大小”
extern int dlink_size();// 获取“双向链表中第index位置的元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get(int index);
// 获取“双向链表中第1个元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get_first();
// 获取“双向链表中最后1个元素”。成功,返回节点指针;否则,返回NULL。
extern void* dlink_get_last();// 将“value”插入到index位置。成功,返回0;否则,返回-1。
extern int dlink_insert(int index, void *pval);
// 将“value”插入到表头位置。成功,返回0;否则,返回-1。
extern int dlink_insert_first(void *pval);
// 将“value”插入到末尾位置。成功,返回0;否则,返回-1。
extern int dlink_append_last(void *pval);// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1
extern int dlink_delete(int index);
// 删除第一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_first();
// 删除组后一个节点。成功,返回0;否则,返回-1
extern int dlink_delete_last();#endif

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

#include <stdio.h>
#include <malloc.h>/*** C 语言实现的双向链表,能存储任意数据。** @author skywang* @date 2013/11/07*/
// 双向链表节点
typedef struct tag_node
{struct tag_node *prev;struct tag_node *next;void* p;
}node;// 表头。注意,表头不存放元素值!!!
static node *phead=NULL;
// 节点个数。
static int  count=0;// 新建“节点”。成功,返回节点指针;否则,返回NULL。
static node* create_node(void *pval)
{node *pnode=NULL;pnode = (node *)malloc(sizeof(node));if (!pnode){printf("create node error!\n");return NULL;}// 默认的,pnode的前一节点和后一节点都指向它自身pnode->prev = pnode->next = pnode;// 节点的值为pvalpnode->p = pval;return pnode;
}// 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{// 创建表头phead = create_node(NULL);if (!phead)return -1;// 设置“节点个数”为0count = 0;return 0;
}// “双向链表是否为空”
int dlink_is_empty()
{return count == 0;
}// 返回“双向链表的大小”
int dlink_size() {return count;
}// 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{if (index<0 || index>=count){printf("%s failed! index out of bound!\n", __func__);return NULL;}// 正向查找if (index <= (count/2)){int i=0;node *pnode=phead->next;while ((i++) < index) pnode = pnode->next;return pnode;}// 反向查找int j=0;int rindex = count - index - 1;node *rnode=phead->prev;while ((j++) < rindex) rnode = rnode->prev;return rnode;
}// 获取“第一个节点”
static node* get_first_node()
{return get_node(0);
}// 获取“最后一个节点”
static node* get_last_node()
{return get_node(count-1);
}// 获取“双向链表中第index位置的元素”。成功,返回节点值;否则,返回-1。
void* dlink_get(int index)
{node *pindex=get_node(index);if (!pindex) {printf("%s failed!\n", __func__);return NULL;}return pindex->p;}// 获取“双向链表中第1个元素的值”
void* dlink_get_first()
{return dlink_get(0);
}// 获取“双向链表中最后1个元素的值”
void* dlink_get_last()
{return dlink_get(count-1);
}// 将“pval”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, void* pval)
{// 插入表头if (index==0)return dlink_insert_first(pval);// 获取要插入的位置对应的节点node *pindex=get_node(index);if (!pindex) return -1;// 创建“节点”node *pnode=create_node(pval);if (!pnode)return -1;pnode->prev = pindex->prev;pnode->next = pindex;pindex->prev->next = pnode;pindex->prev = pnode;// 节点个数+1count++;return 0;
}// 将“pval”插入到表头位置
int dlink_insert_first(void *pval)
{node *pnode=create_node(pval);if (!pnode)return -1;pnode->prev = phead;pnode->next = phead->next;phead->next->prev = pnode;phead->next = pnode;count++;return 0;
}// 将“pval”插入到末尾位置
int dlink_append_last(void *pval)
{node *pnode=create_node(pval);if (!pnode)return -1;pnode->next = phead;pnode->prev = phead->prev;phead->prev->next = pnode;phead->prev = pnode;count++;return 0;
}// 删除“双向链表中index位置的节点”。成功,返回0;否则,返回-1。
int dlink_delete(int index)
{node *pindex=get_node(index);if (!pindex) {printf("%s failed! the index in out of bound!\n", __func__);return -1;}pindex->next->prev = pindex->prev;pindex->prev->next = pindex->next;free(pindex);count--;return 0;
}    // 删除第一个节点
int dlink_delete_first()
{return dlink_delete(0);
}// 删除组后一个节点
int dlink_delete_last()
{return dlink_delete(count-1);
}// 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{if (!phead){printf("%s failed! dlink is null!\n", __func__);return -1;}node *pnode=phead->next;node *ptmp=NULL;while(pnode != phead){ptmp = pnode;pnode = pnode->next;free(ptmp);}free(phead);phead = NULL;count = 0;return 0;
}

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

#include <stdio.h>
#include "double_link.h"/*** C 语言: 双向链表实现栈,能存储任意数据。** @author skywang* @date 2013/11/07*/
// 创建栈
int create_dlink_stack()
{return create_dlink();
}// 销毁栈
int destroy_dlink_stack()
{return destroy_dlink();
}// 将val添加到栈中
int push(void *p)
{return dlink_insert_first(p);
}// 返回“栈顶元素值”
void* peek()
{return dlink_get_first();
}// 返回“栈顶元素值”,并删除“栈顶元素”
void* pop()
{void *p = peek();dlink_delete_first();return p;
}// 返回“栈”的大小
int size()
{return dlink_size();
}// 返回“栈”是否为空
int is_empty()
{return dlink_is_empty();
}typedef struct tag_stu
{int id;char name[20];
}stu;static stu arr_stu[] =
{{10, "sky"},{20, "jody"},{30, "vic"},{40, "dan"},
};
#define ARR_STU_SIZE ( (sizeof(arr_stu)) / (sizeof(arr_stu[0])) )static void print_stu(stu *p)
{if (!p)return ;printf("id=%d, name=%s\n", p->id, p->name);
}void main()
{stu *pval=NULL;// 创建“栈”create_dlink_stack();// 将10, 20, 30 依次推入栈中int i=0;for (i=0; i<ARR_STU_SIZE-1; i++){push(&arr_stu[i]);}// 将“栈顶元素”赋值给pval,并删除“栈顶元素”pval = (stu*)pop();//print_stu(pval) ;// 只将“栈顶”赋值给pval,不删除该元素.pval = peek();//print_stu(pval) ;push(&arr_stu[ARR_STU_SIZE-1]);// 打印栈中的所有元素while (!is_empty()){pval = pop();print_stu(pval) ;}// 销毁栈destroy_dlink_stack();
}

运行结果:

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)

#ifndef ARRAY_STACK_HXX
#define ARRAY_STACK_HXX#include <iostream>
#include "ArrayStack.h"
using namespace std;template<class T> class ArrayStack{public:ArrayStack();~ArrayStack();void push(T t);T peek();T pop();int size();int isEmpty();private:T *arr;int count;
};// 创建“栈”,默认大小是12
template<class T>
ArrayStack<T>::ArrayStack()
{arr = new T[12];if (!arr) {cout<<"arr malloc error!"<<endl;}
}// 销毁“栈”
template<class T>
ArrayStack<T>::~ArrayStack()
{if (arr) {delete[] arr;arr = NULL;}
}// 将val添加到栈中
template<class T>
void ArrayStack<T>::push(T t)
{//arr[count++] = val;arr[count++] = t;
}// 返回“栈顶元素值”
template<class T>
T ArrayStack<T>::peek()
{return arr[count-1];
}// 返回“栈顶元素值”,并删除“栈顶元素”
template<class T>
T ArrayStack<T>::pop()
{int ret = arr[count-1];count--;return ret;
}// 返回“栈”的大小
template<class T>
int ArrayStack<T>::size()
{return count;
}// 返回“栈”是否为空
template<class T>
int ArrayStack<T>::isEmpty()
{return size()==0;
}#endif

栈的测试程序(Main.cpp)

#include <iostream>
#include "ArrayStack.h"
using namespace std;int main()
{int tmp=0;ArrayStack<int> *astack = new ArrayStack<int>();cout<<"main"<<endl;// 将10, 20, 30 依次推入栈中astack->push(10);astack->push(20);astack->push(30);// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = astack->pop();cout<<"tmp="<<tmp<<endl;// 只将“栈顶”赋值给tmp,不删除该元素.tmp = astack->peek();astack->push(40);while (!astack->isEmpty()){tmp = astack->pop();cout<<tmp<<endl;}return 0;
}

运行结果:

main
tmp=30
40
20
10

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

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

实现代码(StlStack.cpp)

#include <iostream>
#include <stack>
using namespace std;/*** C++ 语言: STL 自带的“栈”(stack)的示例。** @author skywang* @date 2013/11/07*/
int main ()
{int tmp=0;stack<int> istack;// 将10, 20, 30 依次推入栈中istack.push(10);istack.push(20);istack.push(30);// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”istack.pop();// 只将“栈顶”赋值给tmp,不删除该元素.tmp = istack.top();istack.push(40);while (!istack.empty()){tmp = istack.top();istack.pop();cout<<tmp<<endl;}return 0;
}

运行结果:

40
20
10

栈的Java实现

和C++一样,JDK包中也提供了”栈”的实现,它就是集合框架中的Stack类。关于Stack类的原理,在”Java 集合系列07之 Stack详细介绍(源码解析)和使用示例”中,已经详细介绍过了。本部分给出2种Java实现
Java实现一:数组实现的栈,能存储任意类型的数据。
Java实现二:Java的 Collection集合 中自带的”栈”(stack)的示例。

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

实现代码(GeneralArrayStack.java)

/*** Java : 数组实现的栈,能存储任意类型的数据** @author skywang* @date 2013/11/07*/
import java.lang.reflect.Array;public class GeneralArrayStack<T> {private static final int DEFAULT_SIZE = 12;private T[] mArray;private int count;public GeneralArrayStack(Class<T> type) {this(type, DEFAULT_SIZE);}public GeneralArrayStack(Class<T> type, int size) {// 不能直接使用mArray = new T[DEFAULT_SIZE];mArray = (T[]) Array.newInstance(type, size);count = 0;}// 将val添加到栈中public void push(T val) {mArray[count++] = val;}// 返回“栈顶元素值”public T peek() {return mArray[count-1];}// 返回“栈顶元素值”,并删除“栈顶元素”public T pop() {T ret = mArray[count-1];count--;return ret;}// 返回“栈”的大小public int size() {return count;}// 返回“栈”是否为空public boolean isEmpty() {return size()==0;}// 打印“栈”public void PrintArrayStack() {if (isEmpty()) {System.out.printf("stack is Empty\n");}System.out.printf("stack size()=%d\n", size());int i=size()-1;while (i>=0) {System.out.println(mArray[i]);i--;}}public static void main(String[] args) {String tmp;GeneralArrayStack<String> astack = new GeneralArrayStack<String>(String.class);// 将10, 20, 30 依次推入栈中astack.push("10");astack.push("20");astack.push("30");// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = astack.pop();System.out.println("tmp="+tmp);// 只将“栈顶”赋值给tmp,不删除该元素.tmp = astack.peek();System.out.println("tmp="+tmp);astack.push("40");astack.PrintArrayStack();    // 打印栈}
}

运行结果:

1 tmp=30
2 tmp=20
3 stack size()=3
4 40
5 20
6 10

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

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

实现代码(StackTest.java)

import java.util.Stack;/*** Java : java集合包中的Stack的演示程序** @author skywang* @date 2013/11/07*/
public class StackTest {public static void main(String[] args) {int tmp=0;Stack<Integer> astack = new Stack<Integer>();// 将10, 20, 30 依次推入栈中astack.push(10);astack.push(20);astack.push(30);// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”tmp = astack.pop();//System.out.printf("tmp=%d\n", tmp);// 只将“栈顶”赋值给tmp,不删除该元素.tmp = (int)astack.peek();//System.out.printf("tmp=%d\n", tmp);astack.push(40);while(!astack.empty()) {tmp = (int)astack.pop();System.out.printf("tmp=%d\n", tmp);}}
}

运行结果:

tmp=40
tmp=20
tmp=10

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

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

  1. Leetcode刷题 155题: 最小栈(基于python3和c++两种语言)

    ** Leetcode刷题 155题: 最小栈(基于python3和c++两种语言) ** ** 题目: ** 设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈. ...

  2. 哪一种语言最流行?VB,C++,JAVA? (转)

    哪一种语言最流行?VB,C++,JAVA? (转)[@more@] Who's Number One? Java, VB, or C++? Three market research firms gi ...

  3. 关于A+B+C问题4种语言的解决办法,Java、C语言、C++、Python

    原题是这个样子的: 这是一个非常简单的题目,意在考察你编程的基础能力.千万别想难了哦.输入为一行,包括了用空格分隔的三个整数A.B.C(数据范围均在-40~40之间).输出为一行,为"A+B ...

  4. 二叉查找树(一)之 图文解析 和 C语言的实现

    本文转载至http://www.cnblogs.com/skywang12345/p/3576328.html 二叉查找树(一)之 图文解析 和 C语言的实现 概要 本章先对二叉树的相关理论知识进行介 ...

  5. java解析xml的几种方式

    java解析xml的几种方式 博客分类: java基础备忘-好记性不然烂笔头 XMLJava应用服务器数据结构编程  第一种:DOM. DOM的全称是Document Object Model,也即文 ...

  6. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必问之 链表 + 栈 + 队列 部分!

    链表 链表是最基本的数据结构,面试官也常常用链表来考察面试者的基本能力,而且链表相关的操作相对而言比较简单,也适合考察写代码的能力.链表的操作也离不开指针,指针又很容易导致出错. 综合多方面的原因,链 ...

  7. 数据结构图文解析之:哈夫曼树与哈夫曼编码详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  8. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必问之 排序 + 二叉树 部分!

    排序 所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序.这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后的数据便于筛选和计算,大大提高了计算效率. 对于排序: 我 ...

  9. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」必知必会 排序 + 二叉树 部分!

    排序 时光小说网 https://wap.youxs.org/ 所谓排序算法,即通过特定的算法因式将一组或多组数据按照既定模式进行重新排序.这种新序列遵循着一定的规则,体现出一定的规律,因此,经处理后 ...

  10. 面试必备:高频算法题汇总「图文解析 + 教学视频 + 范例代码」之 字符串处理+动态规划 合集!

    Attention 秋招接近尾声,我总结了 牛客.WanAndroid 上,有关笔试面经的帖子中出现的算法题,结合往年考题写了这一系列文章,所有文章均与 LeetCode 进行核对.测试.欢迎食用 本 ...

最新文章

  1. python 爬取svg数据_python处理svg数据
  2. html5显示字幕信息,HTML5 Placeholder实现input背景文字提示效果
  3. MyBatis学习 之 二、SQL语句映射文件(1)resultMap
  4. 解决笔记本重装问题(VISTA系统改为XP系统)
  5. 洛谷P3349:小星星(容斥dp)
  6. python监控服务器信息,Python监控服务器实现邮件微信报警
  7. [转]我是如何走进黑客世界的?
  8. mysql sqlite转换_数据库转换工具(SqliteToMysql)
  9. github上成员贡献量_真祖传代码!你的GitHub代码已打包运往北极,传给1000年后人类...
  10. linux系统平均价格,简单认识Linux系统平均负载
  11. html界面等待状态,html 等待界面
  12. java面试题总结(三)----本文都是笔试题,值得学习
  13. OpenJudge NOI 1.5 25:求特殊自然数
  14. [NOIp2008] 双栈排序 (二分图染色 + 贪心)
  15. 中级通信工程师报名-在线题库-历年真题-模拟试题
  16. 牛与马的把表情包(带有改进)
  17. 射线法进行地理空间坐标计算
  18. BIOS怎么开启UEFI模式|电脑设置UEFI启动的方法
  19. 计算机知识对于老师的帮助,教师计算机学习心得体会
  20. string字符串常见用法

热门文章

  1. 数据库系统原理——实验四
  2. Typora上传图片终于解决了
  3. 计算机保研面试之机器学习
  4. rovio视觉里程计的笔记
  5. Word 插入参考文献 通过尾注插入并更改尾注罗马数字为阿拉伯数字
  6. 如何在UltraCompare中编辑文件?
  7. 见贤思齐与三人行必有我师
  8. Java设计模式鸭子模式_[JS设计模式]:鸭子类型与多态
  9. 免费试用微软云服务Azure(无需信用卡版)
  10. 盘点Windows10系统的使用小技巧二 —— 磁贴