栈跟队列的理解

一、栈

  • 栈(stack),是一种线性存储结构,它有以下几个特点:

    • 栈中数据是按照"后进先出(LIFO, Last In First Out)"方式进出栈的;

    • 向栈中添加/删除数据时,只能从栈顶进行操作;

  • 栈通常包括的三种操作:push、peek、pop

    • push -- 向栈中添加元素

    • peek -- 返回栈顶元素

    • pop -- 返回并删除栈顶元素的操作

  1. 使用栈设计一个先进先出的队列


/**
 * 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();
  1. 数据打印为

    
    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
  2. 使用自定义数组实现栈的功能

    
    /**
     * 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]);
            }
        }
    }
    
  3. 相应的我们也要验证实现队列的方式

    
    
    /**
     * 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() );
            }
        }
    }
    
  4. 检验的代码

    
            //验证第一种正常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();
  5. 得到打印数据

    
        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)"方式进出队列的。

    • 队列只允许在"队首"进行删除操作,而在"队尾"进行插入操作。

    • 队列通常包括的两种操作:入队列 和 出队列

  1. 队列的实现



/**
 * 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;
    }

}

猜你喜欢

转载自blog.csdn.net/wei_ai_n/article/details/80233392