数据结构——栈的java实现(一)-使用顺序存储结构(数组)以及实现
2020-01-13 02:03
579 查看
文章目录
一、线性表的定义
线性表是同一类型数据的一个
有限序列,线性表中数据
元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是
首尾相接的。
线性表的顺序存储要求
地址空间是连续的,地址必须一个接一个,不能中断。如下图为顺序存储结构:
二、顺序存储结构
线性表的
顺序存储每个节点只包含数据部分,不需要额外包含数据之间的关系,因为
数据之间的关系通过
地址连续来体现,所以
非常省空间
它的优点访问非常快速,因为地址是连续的,只要知道首地址,任意一个元素的地址都可以算出来。假设每个地址占c个空间,则第i个地址为(i-1)*c。
它的缺点是在插入和删除数据时,可能要移动许多数据,比如一个10000个元素的有序数据,如果我删除了第二个元素,为了继续保持地址连续,所以要把后面9999个元素都向前移动。
三、栈的定义
栈(stack)是限定仅在
表尾进行
插入和删除操作的线性表。
我们把允许插入和删除的一端称为
栈顶(top),另一端称为
栈底(bottom)。
栈又称作后进先出线性表——
Last In First Out(LIFO)
注意:栈是一个被限制的线性表,不提供从中间任何位置删除、插入、访问元素的方法。也就是说栈
只能够在栈顶插入和删除元素。
栈来自与线性表,因此
栈可以使用
顺序表的方式来实现也可以使用
链表的方式来实现。
系统栈记录中断的点,调用完其他方法后继续运行
代码:
Array.class
package code.ArrayCode; public class Array<E> { private E[] data; private int size; /* * 构造函数,传入数据的容量capacity构造Array * */ public Array(int capacity){ data = (E[])new Object[capacity]; size = 0; } //无参数的构造函数,默认数据的容量capacity=10 public Array(){ this(10); } //获取数组中的元素个数 public int getSize(){ return size; } //获取数组的容量 public int getCapacity(){ return data.length; } //返回数组是否为空 public boolean isEmpty(){ return size==0; } //在最后一位添加数据 public void addLast(E e){ add(size,e); } //在开头添加数据 public void addFirst(E e){ add(0,e); } public void add(int index , E e){ //判断index是不是合法的 // 如果index为负数则不合法 // 如果index > size则说明数组中间有空余的位置,并非紧密排列 if(index < 0 || index > size){ throw new IllegalArgumentException("Add failed. Require index >= 0 || index <= size."); } //判断数组满了没有 if(size == data.length){ resize(2 * data.length); } //从最后一位开始移位,当i=index的时候,index位置上还是有原来位置的数据, //只不过index和index+1这两个位置的数据一样,原来index位置上的值复制到了index+1 //所以我们可以放心的用新数据覆盖掉index位置上的值 for(int i = size -1 ; i >= index ; i--){ data[i+1] = data[i]; } //用新值覆盖原index位置上的值 data[index] = e; size++; } //取出索引为index的这个元素 //通过get方法是无法获取没有值的索引 E get(int index){ if(index < 0 || index > size){ throw new IllegalArgumentException("Get failed. Require index >= 0 || index <= size."); } return data[index]; } //在指定索引位置修改数据 void set(int index, E e){ if(index < 0 || index > size){ throw new IllegalArgumentException("Set failed. Require index >= 0 || index <= size."); } data[index] = e; } //查找数组中是否有元素e public boolean contains(E e){ for(int i =0 ; i < size; i++){ if(data[i].equals(e)){ return true; } } return false; } //查找数组中元素e所在的索引,如果不存在元素e,则返回-1 public int find(E e){ for(int i =0 ; i < size; i++){ if(data[i].equals(e)){ return i; } } return -1; } //从数组中删除index位置的元素,返回删除的元素 public E remove(int index){ if(index < 0 || index > size){ throw new IllegalArgumentException("Remove failed. Require index >= 0 || index <= size."); } E ret = data[index]; for(int i = index+1 ; i<size ; i++){ //把后边的值赋给前面的值,覆盖掉前面节点的值,实现删除作用 data[i-1] = data[i]; } size--; //把size索引所在的值设置为null,让它被垃圾回收 data[size] = null; if(size == data.length / 4 && data.length / 2 !=0){ resize(data.length / 2); } return ret; } //从数组中删除第一个元素,返回删除的元素 public E removeFirst(){ return remove(0); } //从数组中删除最后一个元素,返回删除的元素 public E removeLast(){ return remove(size-1); } //从数组中删除元素e public void removeElement(E e){ int index = find(e); if(index != -1){ remove(index); } } public E getLast(){ return get(size-1); } public E getFirst(){ return get(0); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append(String.format("Array: size = %d , capacity = %d\n" , size, data.length)); res.append("["); for(int i =0 ; i < size ; i++){ res.append(data[i]); //如果当前size不是最后一个,则添加一个, if(i != size-1){ res.append(", "); } } res.append("]"); return res.toString(); } //增容和缩容操作 private void resize(int newCapacity){ E[] newData = (E[])new Object[newCapacity]; for(int i =0 ; i < size ; i++){ newData[i] = data[i]; } data = newData; } public void test(){ int[] arr = new int[20]; for(int i=0;i<arr.length;i++){ arr[i]=i; } //scores开辟三个int值的数组 int[] scores = new int[]{100,99,66}; for(int i=0;i<scores.length;i++){ System.out.println(scores[i]); } } }
ArrayStack.class
package code.ArrayCode; public class ArrayStack<E> implements Stack<E> { Array<E> array; public ArrayStack(int capacity){ array = new Array(capacity); } public ArrayStack(){ array = new Array(); } public int getSize() { return array.getSize(); } public boolean isEmpty() { return array.isEmpty(); } public int getCapacity(){ return array.getCapacity(); } public void push(E e) { array.addLast(e); } public E pop() { return array.removeLast(); } public E peek() { return array.getLast(); } @Override public String toString(){ StringBuilder res = new StringBuilder(); res.append("Stack: "); res.append("["); for(int i =0 ; i < array.getSize() ; i++){ res.append(array.get(i)); //如果当前size不是最后一个,则添加一个, if(i != array.getSize() -1){ res.append(", "); } } res.append("] top"); return res.toString(); } }
Stack.class
package code.ArrayCode; public interface Stack<E> { int getSize(); boolean isEmpty(); void push(E e); E pop(); E peek(); }
测试:
public class Main { public static void main(String[] args) { Array<Integer> arr = new Array(); for(int i=0;i<10;i++){ arr.addLast(i); } System.out.println(arr); arr.add(1,100); System.out.println(arr); arr.addFirst(-1); System.out.println(arr); //[-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] arr.remove(2); System.out.println(arr); arr.removeElement(4); System.out.println(arr); arr.removeFirst(); System.out.println(arr); for(int i = 0 ; i < 5 ; i ++){ arr.removeFirst(); } System.out.println(arr); } }
测试结果:
Array: size = 10 , capacity = 10 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Array: size = 11 , capacity = 20 [0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] Array: size = 12 , capacity = 20 [-1, 0, 100, 1, 2, 3, 4, 5, 6, 7, 8, 9] Array: size = 11 , capacity = 20 [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Array: size = 10 , capacity = 20 [-1, 0, 1, 2, 3, 5, 6, 7, 8, 9] Array: size = 9 , capacity = 20 [0, 1, 2, 3, 5, 6, 7, 8, 9] Array: size = 4 , capacity = 10 [6, 7, 8, 9]
总结:
- 点赞 1
- 收藏
- 分享
- 文章举报
相关文章推荐
- 数据结构——队列的java实现(一)-使用顺序存储结构(数组)以及实现
- Java中队列的实现(1)-使用顺序存储结构(数组)以及实现
- 数据结构——队列的java实现(三)-使用单向链表以及实现
- Java中栈的实现(1)-使用顺序存储结构(数组)以及实现
- 数据结构:使用java实现单链表的构造以及基本操作
- 数据结构——栈的java实现(二)-使用单向链表以及实现
- 安卓使用Gson解析服务器返回Json数组,以及java服务器怎样返回list集合的Json数据(原创)
- 【数据结构与算法】数组应用1:矩阵乘法(Java实现)
- 数据结构:java数组特点以及声明数组类
- 数据结构中怎样用先根和中根以及中根和后根建立一颗二叉树(Java语言实现)
- 数据结构与算法-----队列-使用数组(顺序结构)实现
- 树的简单介绍、java实现二叉树的数据关系存储、以及多维数组的存储演示
- 马士兵 Java 第5章(1) 分别使用面向对象和面向结构(数组)的设计方法来实现“数三退一”
- 数据结构——使用双端链表实现队列(java实现)
- java 数组与链表的嵌套使用(数组链表--数据结构)
- 使用PLSQL Developer来实现不同数据库的表结构以及表数据同步
- 数据结构----数组(java实现代码)
- 第十七题:使用数组结构实现大小固定栈(Java)
- 数据结构之数组的增删改查-java实现
- 数据结构之数组和字符串的反转java实现