大话数据结构七:两栈共享存储空间(双向栈)

1. 为什么要使用双向栈?

通过上一篇博客 - 特殊的线性表(栈),不难知道栈的顺序存储(数组实现)性能相对较好,因为它不存在插入和删除时移动元素的问题,但是它有一点缺陷:要事先确定数组存储容量的大小,万一不够,就需要扩充数组容量。这时双向栈就派上用场了,它可以最大限度的利用事先开辟的存储空间。


2. 双向栈有什么特点?

数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为数组的末端,即下标为数组长度M-1处。这样,两个栈如果增加元素,就会从两端点向中间延伸(如下图)。



3. Java实现双向栈

[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 双向栈的数组实现  
  2. public class ShareStack<T> {  
  3.     private Object[] arr; // 数组实现栈的操作  
  4.     private int top1; // 栈1: 栈顶指针  
  5.     private int top2; // 栈2: 栈顶指针  
  6.     private static Integer DEFAULT_SIZE = 16// 数组默认长度  
  7.     private static final Integer STACK_1 = 1// 栈1  
  8.     private static final Integer STACK_2 = 2// 栈2  
  9.   
  10.     public ShareStack() {  
  11.         init();  
  12.     }  
  13.   
  14.     public ShareStack(int size) {  
  15.         DEFAULT_SIZE = size;  
  16.         init();  
  17.     }  
  18.   
  19.     // 初始化栈  
  20.     public void init() {  
  21.         arr = new Object[DEFAULT_SIZE];  
  22.         this.top1 = -1;  
  23.         this.top2 = DEFAULT_SIZE;  
  24.     }  
  25.   
  26.     // 压栈  
  27.     public boolean push(int stackNum, T data) {  
  28.         if (top1 + 1 == top2) { // 栈已满  
  29.             System.out.println("栈已满,不能再push元素了..");  
  30.             return false;  
  31.         }  
  32.         if (stackNum == STACK_1) { // 操作的是栈1  
  33.             arr[++top1] = data; // 栈1前进一位  
  34.             return true;  
  35.         } else if (stackNum == STACK_2) { // 操作的是栈2  
  36.             arr[--top2] = data; // 栈2后退一位  
  37.             return true;  
  38.         } else {  
  39.             System.out.println("请输入正确的栈编号: 1 或 2");  
  40.             return false;  
  41.         }  
  42.     }  
  43.   
  44.     // 弹栈  
  45.     @SuppressWarnings("unchecked")  
  46.     public T pop(int stackNum) {  
  47.         if (stackNum == STACK_1) { // 操作的是栈1  
  48.             if (top1 == -1) {  
  49.                 System.out.println("栈1已经是空栈...");  
  50.                 return null;  
  51.             }  
  52.             return (T) arr[top1--]; // 栈1后退一位  
  53.         } else if (stackNum == STACK_2) { // 操作的是栈2  
  54.             if (top2 == DEFAULT_SIZE) {  
  55.                 System.out.println("栈2已经是空栈...");  
  56.                 return null;  
  57.             }  
  58.             return (T) arr[top2++]; // 栈2前进一位  
  59.         } else {  
  60.             System.out.println("请输入正确的栈编号: 1 或 2");  
  61.             return null;  
  62.         }  
  63.     }  
  64.   
  65.     // 获取栈顶元素  
  66.     @SuppressWarnings("unchecked")  
  67.     public T getTop(int stackNum) {  
  68.         if (stackNum == STACK_1) {  
  69.             if (this.top1 != -1) {  
  70.                 return (T) arr[top1];  
  71.             }  
  72.         } else if (stackNum == STACK_2) {  
  73.             if (stackNum != DEFAULT_SIZE) {  
  74.                 return (T) arr[top2];  
  75.             }  
  76.         } else {  
  77.             System.out.println("请输入正确的栈编号: 1 或 2");  
  78.         }  
  79.         return null;  
  80.     }  
  81.   
  82.     // 获取数组长度  
  83.     public int size() {  
  84.         return DEFAULT_SIZE + top1 + 1 - top2;  
  85.     }  
  86.   
  87.     // 判断是否为空栈  
  88.     public boolean isEmpty() {  
  89.         return this.top1 == -1 && this.top2 == DEFAULT_SIZE;  
  90.     }  
  91.   
  92.     // 置为空栈  
  93.     public boolean clear() {  
  94.         this.top1 = -1;  
  95.         this.top2 = DEFAULT_SIZE;  
  96.         return true;  
  97.     }  
  98.       
  99.     // 测试方法  
  100.     public static void main(String[] args) throws Exception {  
  101.         ShareStack<Integer> stack = new ShareStack<Integer>();  
  102.         stack.push(11);  
  103.         stack.push(22);  
  104.         stack.pop(1);  
  105.         stack.pop(2);  
  106.     }  
  107. }  
4. 什么时候使用双向栈

1.) 两个栈的空间需求有相反关系时,也就是当一个栈增长时另一个栈在缩短的情况。

2.) 两个栈需要具有相同的数据类型,如果数据类型不同,将会使问题复杂化。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值