栈 介绍及简单实现
来源:互联网 发布:淘宝返现卡片 编辑:程序博客网 时间:2024/06/07 02:24
一、栈介绍
1.1 简单介绍
栈(stack) 是一个有序线性表,只能在表的一端(称为栈顶(top))执行插入和删除操作。最后插入的元素最后一个被删除,所以,栈也称为后进先出(LIFO)或先进后出(FILO)线性表。
入栈(push):表示在栈顶插入一个元素。
出栈(pop):表示从栈顶删除一个元素。
试图对一个空栈执行出栈操作称为下溢(underflow)
对一个满栈进行入栈操作称为溢出(overflow)。
通常情况下下溢和溢出均认为异常。
1.2 操作
简单起见,我们使用int类型。
void push(int data) 将data插入栈
int pop() 删除并返回最后一个插入的元素。
int top() 返回一个最后插入的元素。
int size() 返回存储在栈中的元素的个数。
boolean isEmpty() 判断栈中是否有元素
boolean isStackFull() 判断栈中是否存满元素。
1.3 栈的常见应用
- 符号匹配
- 中辍表达式转为后辍表达式
- 计算后辍表达式
- 实现函数调用(包括递归)
- 文本编辑器的撤销操作。
- 浏览器后退按钮的实现。
二、栈的实现
2.1 抽象栈
1
public abstract class Stack {
2
/**
3
* 栈顶插入元素
4
* @param data
5
*/
6
public abstract void push(int data);
7
8
/**
9
* 删除并返回栈顶元素
10
* @return
11
*/
12
public abstract int pop();
13
14
/**
15
* 返回栈顶元素
16
* @return
17
*/
18
public abstract int top();
19
20
/**
21
* 返回栈中元素个数
22
* @return
23
*/
24
public abstract int size();
25
26
/**
27
* 判断栈是否为空
28
* @return
29
*/
30
public abstract boolean isEmpty();
31
32
/**
33
* 判断栈是否满了
34
* @return
35
*/
36
public abstract boolean isStackFull();
37
}
38
我们使用三种方式实现栈,一种是简单数组,一种是动态数组,最后是单向链表
2.2 简单数组实现栈
1
import java.util.Arrays;
2
3
/**
4
* Created by Administrator on 2017/6/24 0024.
5
*/
6
public class SimpleDynamicArrayStack extends Stack {
7
private int top;
8
private int capacity;
9
private int[] array;
10
11
public SimpleDynamicArrayStack(int capacity) {
12
this.capacity = capacity;
13
array = new int[capacity];
14
}
15
16
public void push(int data) {
17
if(isStackFull()){
18
expansion();
19
}
20
array[top] = data;
21
top++;
22
}
23
24
public int pop() {
25
if(isEmpty()){
26
throw new IllegalMonitorStateException("该栈为空栈,无法探出元素");
27
}
28
top--;
29
return array[top-1];
30
}
31
32
public int top() {
33
if(isEmpty()){
34
throw new IllegalMonitorStateException("该栈为空栈,没有元素");
35
}
36
top--;
37
int temp = array[top-1];
38
//如果栈中存储的不是基本数据类型,这里注意将array[top-1]置为null,否则可能出现内存泄漏
39
return temp;
40
}
41
42
public int size() {
43
return 0;
44
}
45
46
public boolean isEmpty() {
47
return top == 0;
48
}
49
50
public boolean isStackFull() {
51
return top == capacity;
52
}
53
54
/**
55
* 数组扩容操作
56
*/
57
private void expansion(){
58
capacity = 2*capacity;
59
array = Arrays.copyOf(array,capacity);
60
}
61
}
62
性能和局限性
性能:假设n为栈中元素个数,在基于简单数组的栈的实现中,各种栈操作的算法复杂度如下:
局限性:栈的最大容量在初始化的时候指定不能改变。
2.2 基于动态数组的实现
我们采取的方式是当栈满了,就能让栈的容量扩充为原来的两倍
1
import java.util.Arrays;
2
3
/**
4
* Created by Administrator on 2017/6/24 0024.
5
*/
6
public class SimpleDynamicArrayStack extends Stack {
7
private int top;
8
private int capacity;
9
private int[] array;
10
11
public SimpleDynamicArrayStack(int capacity) {
12
this.capacity = capacity;
13
array = new int[capacity];
14
}
15
16
public void push(int data) {
17
if(isStackFull()){
18
expansion();
19
}
20
array[top] = data;
21
top++;
22
}
23
24
public int pop() {
25
if(top == 0){
26
throw new IllegalMonitorStateException("该栈为空栈,无法探出元素");
27
}
28
top--;
29
return array[top-1];
30
}
31
32
public int top() {
33
if(isEmpty()){
34
throw new IllegalMonitorStateException("该栈为空栈,没有元素");
35
}
36
top--;
37
int temp = array[top-1];
38
//如果栈中存储的不是基本数据类型,这里注意将array[top-1]置为null,否则可能出现内存泄漏
39
return temp;
40
}
41
42
public int size() {
43
return 0;
44
}
45
46
public boolean isEmpty() {
47
return top == 0;
48
}
49
50
public boolean isStackFull() {
51
return top == capacity;
52
}
53
54
/**
55
* 数组扩容操作
56
*/
57
private void expansion(){
58
capacity = 2*capacity;
59
array = Arrays.copyOf(array,capacity);
60
}
61
}
62
性能:假设n为栈中元素个数。算法复杂度如下
1
/**
2
链表节点
3
*/
4
public class Node {
5
private int data;
6
private Node next;
7
8
public Node(int data) {
9
this.data = data;
10
11
}
12
13
public int getData() {
14
return data;
15
}
16
17
public void setData(int data) {
18
this.data = data;
19
}
20
21
public Node getNext() {
22
return next;
23
}
24
25
public void setNext(Node next) {
26
this.next = next;
27
}
28
}
29
30
31
32
import cn.lx.node.Node;
33
34
/**
35
* Created by Administrator on 2017/6/24 0024.
36
*/
37
public class SimpleNodeStack extends Stack{
38
private Node headNode;
39
private int size;
40
41
public void push(int data) {
42
Node node = new Node(data);
43
if(isEmpty()){
44
headNode = node;
45
return;
46
}
47
size++;
48
node.setNext(headNode);
49
headNode = node;
50
}
51
52
53
public int pop() {
54
if(isEmpty()){
55
throw new IllegalMonitorStateException("该栈为空栈,无法探出元素");
56
}
57
int temp = headNode.getData();
58
headNode = headNode.getNext();
59
size--;
60
return temp;
61
}
62
63
64
public int top() {
65
if(isEmpty()){
66
throw new IllegalMonitorStateException("该栈为空栈,无法探出元素");
67
}
68
69
int temp = headNode.getData();
70
return temp;
71
}
72
73
74
public int size() {
75
return 0;
76
}
77
78
79
public boolean isEmpty() {
80
return headNode == null;
81
}
82
83
84
public boolean isStackFull() {
85
return false;
86
}
87
}
88
性能:假设栈中元素个数为n,算法复杂度如下:
2.4 栈的实现方式比较
基于数组与基于链表的比较:
基于数组实现:
各个操作都是常数时间开销
每隔一端时间倍增操作的开销较大
基于链表实现
栈规模大的增加和减少都很简洁
每个操作都是常数时间开销
每个操作都都要使用额外的空间和时间来处理指针。
阅读全文
0 0
- 栈 介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- 线程池的介绍及简单实现
- oracle锁表当客户端杀掉会话不成功可以服务端杀掉进程
- Android 面试之 Android 篇 发表于 2016-10-27 | 分类于 Android 面试 | | 阅读次数 2249 本文出自 Eddy Wiki ,转载请注
- 开发实现C++ RTMP直播推流sdk
- union
- 算法map简单用法
- 栈 介绍及简单实现
- 转换函数
- Unix/Linux编程实践教程–chmod在Centos7.3的实现
- JVM内存划分
- Eclipse防止定义变量名时后面追加类型后缀
- iOS 运用Runtime机制扩大UIButton的响应区域
- Android利用activity-alias动态更新图标icon,标题label
- 在Java中如何遍历Map对象
- android传输图片数据给java后台(HTML)原始封装
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
惠水县
惠水
贵州惠水县
惠水县属于哪个市
惠水县百鸟河风景区
惠水县连江酒店
惠水吧
惠水招聘
惠水在线
惠水在线招聘
惠水有什么好玩的地方
惠泉啤酒
惠泉
惠泉黄酒
惠泉啤酒代理
惠泉啤酒品种及价格
惠泉啤酒图片
惠泉啤酒多少钱一瓶
惠泉啤酒股票
600573
慧泽
55hz,net
844688
588hz.net
慧泽网
588nznet
玉女派的男掌门 汝之不惠
惠润洗发水
惠润
惠润柔净洗发露
惠润洗发水怎么样
惠润进口洗发水
资生堂惠润洗发水怎么样
资生堂惠润洗发水
资生堂惠润
资生堂惠润洗发水好用吗
惠润沐浴露
惠特皮鞋
惠特
惠特皮鞋什么档次
惠特休闲皮鞋