【Java数据结构的实现】之系列四栈的数组实现ArrayStack

【Java数据结构的实现】之系列四栈的数组实现(使用数组实现栈)

上一节我们一起学习了:栈的实现(使用栈计算后缀表达式),上节中栈的实现,我们使用的是java.util.Stack;来实现的栈,本章使用数组来实现,顺便介绍java.util.Stack。 

4.1本节学习目标

  • 栈的数组实现
  • java.util.Stack讲解

 

 

4.1.1栈的数组实现

       前面的教程中,我们一节学习了栈的基本特性,同时还使用了栈来求解一个问题(后缀表达式),细心的读者可以发现,我们根本不知道栈是如何实现的,这节,我们将探讨栈的实现。

栈的实现有多种方式,本节将介绍上述两种实现方式。

①栈的数组实现的思路:

  1. 数组是一个对象引用的数组,其数据类型在栈实例化时确定,使用泛型。
  2. 栈底在数组的index(索引)为0处。
  3. 栈的元素是安顺序存储在数组中
  4. 有个top变量,这个top变量包含两个含义:数组元素的数目和下一个可添加元素的索引位置。

我们可以用个实例图来表示上述的这个实现:

 

 底  0             1             2            3             4              5            6            7            8             ……

A

B

C

D

E

 

 

 

 

 

 top 5

则表示:

  • 栈底为索引位置0,
  • 数组的大小为5 ,
  • 下一个插入栈中的元素的索引位置为 5

程序关键部分有详细的注释。

②StackADT,是我们第二接里面的栈的抽象数据类型的定义:

如下:

 
 
  1. public interface StackADT<T> {  
  2.     /**  
  3.      * 往栈顶添加一个元素  
  4.      * */ 
  5.     public void push(T element);  
  6.     /**  
  7.      * 从栈顶移除一个元素,并返回该元素  
  8.      * */ 
  9.     public T pop();  
  10.     /**  
  11.      * 返回但不移除栈顶元素  
  12.      * */ 
  13.     public T peek();  
  14.     /**  
  15.      * 判断是否为空  
  16.      * */ 
  17.     public boolean isEmpty();  
  18.     /**  
  19.      * 返回栈大小  
  20.      * */ 
  21.     public int size();  
  22.     /**  
  23.      * 返回栈的字符串的表示 toString  
  24.      * */ 
  25.     //public String toString();  
  26. }  

③ArrayStack 实现StackADT接口
程序详解:

  1. public class ArrayStack<T> implements StackADT<T>{  
  2.     /**标识数组默认容量的变量*/ 
  3.     private final int DEFAULT_CAPACITY = 100;  
  4.     /**标识数组的元素数目及下一个可用位置(下一元素压入位置)*/ 
  5.     private int top;  
  6.     /**标识栈的泛型元素数组*/ 
  7.     private T[] stack;  
  8.     /**  
  9.      * 使用默认容量创建一个空栈  
  10.      * */ 
  11.     public ArrayStack() {  
  12.         top = 0;  
  13.         stack =  (T[]) (new Object[DEFAULT_CAPACITY]);//实例化一个Object数组,然后转化为一个泛型数组  
  14.     }  
  15.     /**  
  16.      * 使用指定容量创建一个空栈,参数initialCapacity标识的是指定的容量  
  17.      * */ 
  18.     public ArrayStack(int initialCapacity) {  
  19.         top = 0;  
  20.         stack = (T[]) (new Object[initialCapacity]);  
  21.     }  
  22.  
  23.         判断栈是否为空
  24.     public boolean isEmpty() {  
  25.          if(size()==0) {  
  26.              return true;  
  27.          }else {  
  28.              return false;  
  29.          }  
  30.     }  
  31.  
  32.         出栈操作,栈为空,则出栈失败
  33.     public T peek() {  
  34.          if(isEmpty()){  
  35.              System.out.println("栈为空,操作失败!");  
  36.              throw new EmptyStackException();  
  37.          }  
  38.         return stack[top-1];  
  39.     }  
  40.  
  41.     /**  
  42.      * 数组实现的pop操作由以下几个步骤组成  
  43.      * ①却保栈不为空  
  44.      * ②计数器top--  
  45.      * ③设置临时引用等于stack[top]的元素  
  46.      * ④设置stack[top]为空  
  47.      * ⑤返回该临时引用  
  48.      * */ 
  49.     public T pop() {  
  50.         if(isEmpty()) {  
  51.             System.out.println("栈为空,出栈失败!");  
  52.             throw  new EmptyStackException();  
  53.               
  54.         }  
  55.         top--;  
  56.         T result = stack[top];//top为栈顶元素,数组从0开始  
  57.         stack[top] = null;  
  58.         return result;  
  59.     }  
  60.  
  61.     /**  
  62.      * 对于栈的数组的实现,其push操作由以下步骤构成  
  63.      * ①确保该数组不是蛮的  
  64.      * ②把数组的top引用设置为要加入到栈中的对象  
  65.      * ③增加top和count的值  
  66.      * */   
  67.     public void push(T element) {  
  68.          if(size()==stack.length) {  
  69.              expandCapacity();  
  70.          }  
  71.          stack[top] = element;  
  72.          top++;  
  73.           
  74.     }  
  75.        
  76.     /**  
  77.      * 使数组的大小加倍。由于数组一旦实例化以后就不能改变其大小,  
  78.      * 因此该方法是创建一个更大的数组,并把旧数组中的内容复制到新数组中  
  79.      * 它是类的一个支持方法,因此可以实现为私有的  
  80.      * */ 
  81.     private void expandCapacity() {  
  82.         T[] larger = (T[]) new Object[stack.length*2];  
  83.          for(int index = 0;index<stack.length;index++){  
  84.              larger[index] = stack[index];  
  85.              stack = larger;  
  86.          }  
  87.           
  88.     }   栈的大小,由变量top控制
  89.     public int size() {  
  90.            
  91.         return top;  
  92.     }  
  93.       
  94.  
  95. }  

 

④ArrayStack.java

 
 
  1. /**  
  2.  * @author 幽灵柯南  
  3.  * 日期 2011.11.16  
  4.  * 功能 用数组实现栈  
  5.  * */ 
  6.  
  7. package com.yaxing.stack;  
  8.  
  9. import java.util.EmptyStackException;  
  10.  
  11. public class ArrayStack<T> implements StackADT<T>{  
  12.     /**标识数组默认容量的变量*/ 
  13.     private final int DEFAULT_CAPACITY = 100;  
  14.     /**标识数组的元素数目及下一个可用位置(下一元素压入位置)*/ 
  15.     private int top;  
  16.     /**标识栈的泛型元素数组*/ 
  17.     private T[] stack;  
  18.     /**  
  19.      * 使用默认容量创建一个空栈  
  20.      * */ 
  21.     public ArrayStack() {  
  22.         top = 0;  
  23.         stack =  (T[]) (new Object[DEFAULT_CAPACITY]);//实例化一个Object数组,然后转化为一个泛型数组  
  24.     }  
  25.     /**  
  26.      * 使用指定容量创建一个空栈,参数initialCapacity标识的是指定的容量  
  27.      * */ 
  28.     public ArrayStack(int initialCapacity) {  
  29.         top = 0;  
  30.         stack = (T[]) (new Object[initialCapacity]);  
  31.     }  
  32.  
  33.        
  34.     public boolean isEmpty() {  
  35.          if(size()==0) {  
  36.              return true;  
  37.          }else {  
  38.              return false;  
  39.          }  
  40.     }  
  41.  
  42.        
  43.     public T peek() {  
  44.          if(isEmpty()){  
  45.              System.out.println("栈为空,操作失败!");  
  46.              throw new EmptyStackException();  
  47.          }  
  48.         return stack[top-1];  
  49.     }  
  50.  
  51.     /**  
  52.      * 数组实现的pop操作由以下几个步骤组成  
  53.      * ①却保栈不为空  
  54.      * ②计数器top--  
  55.      * ③设置临时引用等于stack[top]的元素  
  56.      * ④设置stack[top]为空  
  57.      * ⑤返回该临时引用  
  58.      * */ 
  59.     public T pop() {  
  60.         if(isEmpty()) {  
  61.             System.out.println("栈为空,出栈失败!");  
  62.             throw  new EmptyStackException();  
  63.               
  64.         }  
  65.         top--;  
  66.         T result = stack[top];//top为栈顶元素,数组从0开始  
  67.         stack[top] = null;  
  68.         return result;  
  69.     }  
  70.  
  71.     /**  
  72.      * 对于栈的数组的实现,其push操作由以下步骤构成  
  73.      * ①确保该数组不是蛮的  
  74.      * ②把数组的top引用设置为要加入到栈中的对象  
  75.      * ③增加top和count的值  
  76.      * */   
  77.     public void push(T element) {  
  78.          if(size()==stack.length) {  
  79.              expandCapacity();  
  80.          }  
  81.          stack[top] = element;  
  82.          top++;  
  83.           
  84.     }  
  85.        
  86.     /**  
  87.      * 使数组的大小加倍。由于数组一旦实例化以后就不能改变其大小,  
  88.      * 因此该方法是创建一个更大的数组,并把旧数组中的内容复制到新数组中  
  89.      * 它是类的一个支持方法,因此可以实现为私有的  
  90.      * */ 
  91.     private void expandCapacity() {  
  92.         T[] larger = (T[]) new Object[stack.length*2];  
  93.          for(int index = 0;index<stack.length;index++){  
  94.              larger[index] = stack[index];  
  95.              stack = larger;  
  96.          }  
  97.           
  98.     }  
  99.     public int size() {  
  100.            
  101.         return top;  
  102.     }  
  103.       
  104.  
  105. }  


 ⑤测试方法:

 

 
 
  1. ArrayStack<T> arrayStack = new ArrayStack<T>();  
  2.         arrayStack.push((T) "A");  
  3.         arrayStack.push((T) "B");  
  4.         arrayStack.push((T) "B");  
  5.         arrayStack.push((T) "C");  
  6.         arrayStack.push((T) "D");  
  7.         arrayStack.push((T) "E");  
  8.         arrayStack.push((T) "F");  
  9.         System.out.println();  
  10.         System.out.println("栈的大小:"+arrayStack.size()); 

 ⑥测试结果:

 

 
 
  1. A、B、B、C、D、E、F、  
  2. 栈的大小:7  




本文转自 w156445045 51CTO博客,原文链接:http://blog.51cto.com/enetq/716020 ,如需转载请自行联系原作者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值