概要

本章会先对栈的原理进行介绍,然后分别通过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) 向栈中添加/删除数据时,只能从栈顶进行操作。

栈通常包括的三种操作: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 -;
} return ;
} // 销毁“栈”
int destroy_array_stack()
{
if (arr)
{
free(arr);
arr = NULL;
} return ;
} // 将val添加到栈中
void push(int val)
{
arr[count++] = val;
} // 返回“栈顶元素值”
int peek()
{
return arr[count-];
} // 返回“栈顶元素值”,并删除“栈顶元素”
int pop()
{
int ret = arr[count-];
count--;
return ret;
} // 返回“栈”的大小
int size()
{
return count;
} // 返回“栈”是否为空
int is_empty()
{
return size()==;
} // 打印“栈”
void print_array_stack()
{
if (is_empty())
{
printf("stack is Empty\n");
return ;
} printf("stack size()=%d\n", size()); int i=size()-;
while (i>=)
{
printf("%d\n", arr[i]);
i--;
}
} void main()
{
int tmp=; // 创建“栈”
create_array_stack(); // 将10, 20, 30 依次推入栈中
push();
push();
push(); //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();
print_array_stack(); // 打印栈 // 销毁栈
destroy_array_stack();
}

运行结果

tmp=
tmp=
stack size()=

结果说明:该示例中的栈,是通过"数组"来实现的!
由于代码中已经给出了详细了注释,这里就不再对函数进行说明了。仅对主函数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 ;
} // 将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 -;
} 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 -;
} return phead->val;
} // 返回链表中节点的个数
static int size()
{
int count=;
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 ;
} 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=; // 将10, 20, 30 依次推入栈中
push();
push();
push(); //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();
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=; // 新建“节点”。成功,返回节点指针;否则,返回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;
// 节点的值为value
pnode->value = value; return pnode;
} // 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{
// 创建表头
phead = create_node(-);
if (!phead)
return -; // 设置“节点个数”为0
count = ; return ;
} // “双向链表是否为空”
int dlink_is_empty()
{
return count == ;
} // 返回“双向链表的大小”
int dlink_size() {
return count;
} // 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{
if (index< || index>=count)
{
printf("%s failed! the index in out of bound!\n", __func__);
return NULL;
} // 正向查找
if (index <= (count/))
{
int i=;
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=;
int rindex = count - index - ;
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();
} // 获取“最后一个节点”
static node* get_last_node()
{
return get_node(count-);
} // 获取“双向链表中第index位置的元素的值”。成功,返回节点值;否则,返回-1。
int dlink_get(int index)
{
node *pindex=get_node(index);
if (!pindex)
{
printf("%s failed!\n", __func__);
return -;
} return pindex->value; } // 获取“双向链表中第1个元素的值”
int dlink_get_first()
{
return dlink_get();
} // 获取“双向链表中最后1个元素的值”
int dlink_get_last()
{
return dlink_get(count-);
} // 将“value”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, int value)
{
// 插入表头
if (index==)
return dlink_insert_first(value); // 获取要插入的位置对应的节点
node *pindex=get_node(index);
if (!pindex)
return -; // 创建“节点”
node *pnode=create_node(value);
if (!pnode)
return -; pnode->prev = pindex->prev;
pnode->next = pindex;
pindex->prev->next = pnode;
pindex->prev = pnode;
// 节点个数+1
count++; return ;
} // 将“value”插入到表头位置
int dlink_insert_first(int value)
{
node *pnode=create_node(value);
if (!pnode)
return -; pnode->prev = phead;
pnode->next = phead->next;
phead->next->prev = pnode;
phead->next = pnode;
count++;
return ;
} // 将“value”插入到末尾位置
int dlink_append_last(int value)
{
node *pnode=create_node(value);
if (!pnode)
return -; pnode->next = phead;
pnode->prev = phead->prev;
phead->prev->next = pnode;
phead->prev = pnode;
count++;
return ;
} // 删除“双向链表中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 -;
} pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
count--; return ;
} // 删除第一个节点
int dlink_delete_first()
{
return dlink_delete();
} // 删除组后一个节点
int dlink_delete_last()
{
return dlink_delete(count-);
} // 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{
if (!phead)
{
printf("%s failed! dlink is null!\n", __func__);
return -;
} node *pnode=phead->next;
node *ptmp=NULL;
while(pnode != phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
} free(phead);
phead = NULL;
count = ; return ;
} // 打印“双向链表”
void print_dlink()
{
if (count== || (!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=; // 创建“栈”
create_dlink_stack(); // 将10, 20, 30 依次推入栈中
push();
push();
push(); //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();
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=; // 新建“节点”。成功,返回节点指针;否则,返回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;
// 节点的值为pval
pnode->p = pval; return pnode;
} // 新建“双向链表”。成功,返回0;否则,返回-1。
int create_dlink()
{
// 创建表头
phead = create_node(NULL);
if (!phead)
return -; // 设置“节点个数”为0
count = ; return ;
} // “双向链表是否为空”
int dlink_is_empty()
{
return count == ;
} // 返回“双向链表的大小”
int dlink_size() {
return count;
} // 获取“双向链表中第index位置的节点”
static node* get_node(int index)
{
if (index< || index>=count)
{
printf("%s failed! index out of bound!\n", __func__);
return NULL;
} // 正向查找
if (index <= (count/))
{
int i=;
node *pnode=phead->next;
while ((i++) < index)
pnode = pnode->next; return pnode;
} // 反向查找
int j=;
int rindex = count - index - ;
node *rnode=phead->prev;
while ((j++) < rindex)
rnode = rnode->prev; return rnode;
} // 获取“第一个节点”
static node* get_first_node()
{
return get_node();
} // 获取“最后一个节点”
static node* get_last_node()
{
return get_node(count-);
} // 获取“双向链表中第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();
} // 获取“双向链表中最后1个元素的值”
void* dlink_get_last()
{
return dlink_get(count-);
} // 将“pval”插入到index位置。成功,返回0;否则,返回-1。
int dlink_insert(int index, void* pval)
{
// 插入表头
if (index==)
return dlink_insert_first(pval); // 获取要插入的位置对应的节点
node *pindex=get_node(index);
if (!pindex)
return -; // 创建“节点”
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->prev = pindex->prev;
pnode->next = pindex;
pindex->prev->next = pnode;
pindex->prev = pnode;
// 节点个数+1
count++; return ;
} // 将“pval”插入到表头位置
int dlink_insert_first(void *pval)
{
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->prev = phead;
pnode->next = phead->next;
phead->next->prev = pnode;
phead->next = pnode;
count++;
return ;
} // 将“pval”插入到末尾位置
int dlink_append_last(void *pval)
{
node *pnode=create_node(pval);
if (!pnode)
return -; pnode->next = phead;
pnode->prev = phead->prev;
phead->prev->next = pnode;
phead->prev = pnode;
count++;
return ;
} // 删除“双向链表中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 -;
} pindex->next->prev = pindex->prev;
pindex->prev->next = pindex->next;
free(pindex);
count--; return ;
} // 删除第一个节点
int dlink_delete_first()
{
return dlink_delete();
} // 删除组后一个节点
int dlink_delete_last()
{
return dlink_delete(count-);
} // 撤销“双向链表”。成功,返回0;否则,返回-1。
int destroy_dlink()
{
if (!phead)
{
printf("%s failed! dlink is null!\n", __func__);
return -;
} node *pnode=phead->next;
node *ptmp=NULL;
while(pnode != phead)
{
ptmp = pnode;
pnode = pnode->next;
free(ptmp);
} free(phead);
phead = NULL;
count = ; return ;
}

双向链表的测试程序(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[];
}stu; static stu arr_stu[] =
{
{, "sky"},
{, "jody"},
{, "vic"},
{, "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=;
for (i=; i<ARR_STU_SIZE-; i++)
{
push(&arr_stu[i]);
} // 将“栈顶元素”赋值给pval,并删除“栈顶元素”
pval = (stu*)pop();
//print_stu(pval) ; // 只将“栈顶”赋值给pval,不删除该元素.
pval = peek();
//print_stu(pval) ; push(&arr_stu[ARR_STU_SIZE-]); // 打印栈中的所有元素
while (!is_empty())
{
pval = pop();
print_stu(pval) ;
} // 销毁栈
destroy_dlink_stack();
}

运行结果

id=, name=dan
id=, name=jody
id=, 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[];
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-];
} // 返回“栈顶元素值”,并删除“栈顶元素”
template<class T>
T ArrayStack<T>::pop()
{
int ret = arr[count-];
count--;
return ret;
} // 返回“栈”的大小
template<class T>
int ArrayStack<T>::size()
{
return count;
} // 返回“栈”是否为空
template<class T>
int ArrayStack<T>::isEmpty()
{
return size()==;
} #endif

栈的测试程序(Main.cpp)

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

运行结果

main
tmp=

结果说明:关于"栈的声明和实现都在头文件中"的原因,是因为栈的实现利用了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=;
stack<int> istack; // 将10, 20, 30 依次推入栈中
istack.push();
istack.push();
istack.push(); // 将“栈顶元素”赋值给tmp,并删除“栈顶元素”
istack.pop(); // 只将“栈顶”赋值给tmp,不删除该元素.
tmp = istack.top(); istack.push(); while (!istack.empty())
{
tmp = istack.top();
istack.pop();
cout<<tmp<<endl;
} return ;
}

运行结果


栈的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(); // 打印栈
}
}

运行结果

 tmp=30
tmp=20
stack size()=3
40
20
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)的更多相关文章

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

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

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

    概要 本章和介绍"栈"时的流程一样,先对队列进行介绍,然后分别给出队列的C.C++和Java三种语言的实现.内容包括:1. 队列的介绍2. 队列的C实现3. 队列的C++实现4.  ...

  3. 选择排序的3种语言实现方法(C java python)

    1.选择排序的思路是:遍历数组,第一遍找出所有成员的最小值,放到数组下标为0的位置,第二遍从剩余内容中,再次找出最小值,放到数组下标为1的位置,以此类推,遍历完成所有的数组内容,最后结果就是:数组是按 ...

  4. 数据结构图文解析之:栈的简介及C++模板实现

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

  5. 数据结构图文解析之:直接插入排序及其优化(二分插入排序)解析及C++实现

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

  6. 数据结构图文解析之:数组、单链表、双链表介绍及C++模板实现

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

  7. 数据结构图文解析之:队列详解与C++模板实现

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

  8. 数据结构图文解析之:AVL树详解及C++模板实现

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

  9. 数据结构图文解析之:二叉堆详解及C++模板实现

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

随机推荐

  1. Visual Studio 2012完美的拥抱GitHub

    详情请查看http://www.aehyok.com/Blog/Detail/73.html 个人网站地址:aehyok.com QQ 技术群号:206058845,验证码为:aehyok 本文文章链 ...

  2. VS2013中Python学习笔记[Django Web的第一个网页]

    前言 前面我简单介绍了Python的Hello World.看到有人问我搞搞Python的Web,一时兴起,就来试试看. 第一篇 VS2013中Python学习笔记[环境搭建] 简单介绍Python环 ...

  3. 阿里云产品介绍(二):云服务器ECS的孪生兄弟们

    上一篇介绍的云服务器ECS,是阿里云最基础的产品,也是每一个云计算厂商最基础的产品,俗称爆款.除了标准的云服务器,阿里云也不停的在推出面向特殊业务场地的云服务器,可以说是ECS的孪生兄弟们. 这一篇就 ...

  4. ORA-01033:ORACLE initialization or shutdown in progress

    借用他人的经验 客户Oracle服务器进入PL/SQL Developer时报ora-01033:oracle initializationg or shutdown in progress 错误提示 ...

  5. HDU 4762 Cut the Cake(公式)

    Cut the Cake Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  6. GameOver

    GameOver. 正了八经的觉得GameOver了.该开始新的了.

  7. 图像拼接 SIFT资料合集

    转自 http://blog.csdn.net/stellar0/article/details/8741780 分类: 最近也注意一些图像拼接方面的文章,很多很多,尤其是全景图拼接的,实际上类似佳能 ...

  8. 在线制作h5——上帝的礼物

    在线制作h5 网址:http://www.godgiftgame.com 网站名称:上帝的礼物 推荐指数:5颗星 功能概要 可以设置背景.元素图片.元素文字.元素图形.声音.加载.链接.分享,生成h5 ...

  9. WWDC2016-session401-CodeSign大改版

    自动签名机制和手动签名都明显看起来很好用. 自动签名有log 手动签名有具体的错误提示信息. session401 Xcode Signing. 亲,你的眼睛好大 相声演员吗? Yeah,You ar ...

  10. DataInputStream类和RandomAccessFile类的使用方法

    // DataInputStream类实现了DataInput接口,要想从文件中读入二进制数据, // 你需要将DataInputStream与某个字节源相结合,例如FileInputStream / ...