一、栈
栈(stack),是一种线性存储结构,它有以下几个特点:
栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的;
向栈中添加/删除数据时,只能从栈顶进行操作;
栈通常包括的三种操作:push、peek、pop
push -- 向栈中添加元素
peek -- 返回栈顶元素
pop -- 返回并删除栈顶元素的操作
使用栈设计一个先进先出的队列
/** * description:由于栈是先进后出,队列是先进先出特性,因此使用两个栈, * 全部数据加入到第一个栈,然后在循环压入第二个栈后依次出栈即可先进先出 * Creat by shi on 2018/5/7 */ public class StackTest<T> { private String TAG = "StackTest" ; //创建第一个入栈 public Stack<T> firstStack = new Stack<>(); //创建第二个出栈 public Stack<T> secondStack = new Stack<>(); //数据加入到第一个栈中 public void add(T val){ firstStack.add(val); } public void deleteStack(){ //判断第二个栈为空,将1出压入2中 if (secondStack.isEmpty()){ while (!firstStack.isEmpty()){ secondStack.add(firstStack.pop()); } } if (secondStack.isEmpty()){ throw new RuntimeException("this is add exception"); } //依次出栈打印数据 while (!secondStack.isEmpty()){ Log.e(TAG, "currentStack: " + secondStack.pop() ); } } } //检验打印数据 StackTest<Integer> stack = new StackTest<>(); for (int i = 0; i < 5; i++) { stack.add(i); } //弹出数据 stack.deleteStack();
数据打印为
05-07 20:47:13.800 E/StackTest(25235): currentStack: 0 05-07 20:47:13.800 E/StackTest(25235): currentStack: 1 05-07 20:47:13.800 E/StackTest(25235): currentStack: 2 05-07 20:47:13.800 E/StackTest(25235): currentStack: 3 05-07 20:47:13.800 E/StackTest(25235): currentStack: 4
使用自定义数组实现栈的功能
/** * description:使用数组实现一个栈,其实 Stack extends Vector,底层是线程安全的数组实现的 * Creat by shi on 2018/5/7 */ public class GeneralArrayStack<T> { private String TAG = " GeneralArrayStack" ; private static final int DEFAULT_SIZE = 12; private T[] mArray ; private int count ; public GeneralArrayStack(Class<T> type) { this(type , DEFAULT_SIZE); } //设置一个最大为size的数组 public GeneralArrayStack(Class<T> type, int size) { mArray = (T[]) Array.newInstance(type, size); count = 0 ; } //添加到栈中 public void put(T val){ mArray[count++] = val ; } //得到栈顶数据 public T peek(){ return mArray[count -1] ; } public T pop(){ T t = mArray[count - 1]; count-- ; return t; } //栈的大小 public int size(){ return count; } //是否为空 public boolean isEmpty(){ return size() == 0 ; } //打印栈中的数据 public void printArrayStack(){ if (isEmpty()){ Log.e(TAG, "GeneralArrayStack is empty"); } Log.e(TAG, "GeneralArrayStack.size= " + size() ); int i = size() -1 ; while (i>=0){ Log.e(TAG, "printArrayStack: " + mArray[i]); } } }
相应的我们也要验证实现队列的方式
/** * description:验证自定义两个数组实现的栈是否可以实现队列的需求 * Creat by shiqiang on 2018/5/7 0007 20:35 */ public class GeneralArrayStackTest<T> { private String TAG = "GeneralArrayStackTest" ; //创建第一个入栈 public GeneralArrayStack firstStack = new GeneralArrayStack(Integer.class); //创建第二个出栈 public GeneralArrayStack secondStack = new GeneralArrayStack(Integer.class); //数据加入到第一个栈中 public void add(T val){ firstStack.put(val); } public void deleteStack(){ //判断第二个栈为空,将1出压入2中 if (secondStack.isEmpty()){ while (!firstStack.isEmpty()){ secondStack.put(firstStack.pop()); } } if (secondStack.isEmpty()){ throw new RuntimeException("this is add exception"); } //依次出栈打印数据 while (!secondStack.isEmpty()){ Log.e(TAG, "currentStack: " + secondStack.pop() ); } } }
检验的代码
//验证第一种正常Stack StackTest<Integer> stack = new StackTest<>(); for (int i = 0; i < 5; i++) { stack.add(i); } //弹出数据 stack.deleteStack(); Log.e(TAG, "----------------------------------------- " ); //验证第二种,自定义数组实现的栈 GeneralArrayStackTest<Integer> arrayStackTest = new GeneralArrayStackTest<>(); for (int i = 0; i < 4; i++) { arrayStackTest.add(i); } //弹出数据 arrayStackTest.deleteStack();
得到打印数据
Line 1944: 05-07 20:47:13.800 E/StackTest(25235): currentStack: 0 Line 1946: 05-07 20:47:13.800 E/StackTest(25235): currentStack: 1 Line 1948: 05-07 20:47:13.800 E/StackTest(25235): currentStack: 2 Line 1950: 05-07 20:47:13.800 E/StackTest(25235): currentStack: 3 Line 1952: 05-07 20:47:13.800 E/StackTest(25235): currentStack: 4 Line 1956: 05-07 20:47:13.800 E/GeneralArrayStackTest(25235): currentStack: 0 Line 1958: 05-07 20:47:13.800 E/GeneralArrayStackTest(25235): currentStack: 1 Line 1960: 05-07 20:47:13.800 E/GeneralArrayStackTest(25235): currentStack: 2 Line 1962: 05-07 20:47:13.800 E/GeneralArrayStackTest(25235): currentStack: 3
二、队列
是一种线性存储结构。它有以下几个特点:
队列中数据是按照"先进先出(FIFO, First-In-First-Out)"方式进出队列的。
队列只允许在"队首"进行删除操作,而在"队尾"进行插入操作。
队列通常包括的两种操作:入队列 和 出队列
队列的实现
/** * description:使用数组实现队列,只能实现int型 * Creat by shi on 2018/5/7 */ public class ArrayQueue { private int[] mArray; private int mCount ; public ArrayQueue(int sz) { mArray = new int[sz]; mCount = 0; } //将val添加到队列尾部 public void add(int val){ mArray[mCount++] = val ; } //返回队列头部元素 public int front(){ return mArray[0]; } //返回"队首元素",并删除队首 public int pop(){ int ret = mArray[0]; mCount-- ; //遍历将后值给前面一个值 for (int i = 1; i <= mCount; i++) { mArray[i - 1] = mArray[i]; } return ret ; } // 返回“队列”的大小 public int size() { return mCount; } // 返回“队列”是否为空 public boolean isEmpty() { return size()==0; } }