Javase学习11-栈与队列

Javase学习11-栈与队列

栈:LIFO(Last in First out)后进先出

队列:FIFO(First in First out)先进先出

1. 栈

栈(stack)是一种后进先出(LIFO)的集合类型, 即后添加的数据会先被删除。

类似存取盘子,只从一个口存放

02压栈02.png 03弹栈01.PNG 04弹栈02.PNG

可以用数组和链表实现栈

1.1 用数组实现栈

1.1.1 主类:
/**
 * @Author TSCCG
 * @Date 2021/5/21 18:40
 */

public class Stack<T> {
    //定义栈
    private Object[] elements;
    //定义栈帧
    private int index = -1;

    /**
     * 在构造方法中初始化栈
     * @param size
     */
    public Stack(int size) {
        this.elements = new Object[size];
    }
	/**
     * 设定栈默认大小
     */
    public Stack() {
        this(3);
    }

    /**
     * 压栈方法
     * @param data
     */
    public void push(T data) {
        if (index >= elements.length - 1) {
            System.out.println("栈满,压栈失败!");
            return;
        }
        //栈帧先加1再赋值
        elements[++index] = data;
        System.out.println("压栈" + data + "成功,栈帧指向" + index);
    }

    /**
     * 弹栈方法
     * @return
     */
    public T pop() {
        if (index >= 0) {
            T temp = (T) elements[index];
            index--;
            return temp;
        }
        return null;
    }

    public Object[] getElements() {
        return elements;
    }

    public void setElements(Object[] elements) {
        this.elements = elements;
    }
}
1.1.2 测试类:
/**
 * @author: TSCCG
 * @date: 2021/5/21
 */
public class StackTest {
    public static void main(String[] args) {
        ArrayStack<Object> stack = new ArrayStack<>();
        stack.push("张三");
        stack.push("李四");
        stack.push("王五");
        stack.push("赵六");
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
    }
}

结果:

压栈张三成功,栈帧指向0
压栈李四成功,栈帧指向1
压栈王五成功,栈帧指向2
栈满,压栈失败!
弹出了:王五
弹出了:李四
弹出了:张三
弹出了:null

1.2 用链表实现栈

1.2.1 主类
package stack;

/**
 * @Author TSCCG
 * @Date 2021/5/21 21:52
 */
public class LinkStack <T>{
    private Node head;
    private int size = 0;

    /**
     * 压栈
     */
    public void push(T data) {
        //创建新节点
        Node newNode = new Node(data);
        if (size == 0) {
            //当链表为空时,使新节点成为头节点
            head = newNode;
        } else {
            //当链表不为空时,找到当前链表的末节点,使其指向新节点,新节点成为新的末节点
            findEnd(head).setNext(newNode);
        }
        //链表长度加1
        size++;
        System.out.println("压栈" + data + "成功,栈帧指向" + (size - 1));
    }

    /**
     * 弹栈
     */
    public T pop() {
        if (size >= 0) {
            //将栈顶节点赋给一个临时节点
            Node tempNode = getNode(size - 1);
            //将栈顶节点的值强转成T类型并赋给一个变量
            T temp = (T)tempNode.getData();
            //使栈顶节点为null
            tempNode = null;
            size--;
            return temp;
        }
        return null;
    }

    /**
     * 3.通过下标找到目标节点
     * @return
     */
    public Node getNode(int index) {
        Node tempNode = head;
        for (int i = 0; i < index; i++) {
            tempNode = tempNode.getNext();
        }
        return tempNode;
    }

    /**
     * 3.1通过下标返回该节点的值
     * @param index
     * @return
     */
    public T get(int index) {
        return (T)(getNode(index).getData());
    }
    /**
     * 3.2找到尾节点
     */
    public Node findEnd(Node node) {
        if (node.getNext() == null) {
            return node;
        }
        //使用递归
        return findEnd(node.getNext());
    }

}
1.2.2 测试类
import stack.ArrayStack;
import stack.LinkStack;

/**
 * @author: TSCCG
 * @date: 2021/5/21
 */
public class Test {
    public static void main(String[] args) {
        LinkStack<Object> stack = new LinkStack<>();
        stack.push("张三");
        stack.push("李四");
        stack.push("王五");
        stack.push("赵六");
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
    }
}

结果:

压栈张三成功,栈帧指向0
压栈李四成功,栈帧指向1
压栈王五成功,栈帧指向2
压栈赵六成功,栈帧指向3
弹出了:赵六
弹出了:王五
弹出了:李四
弹出了:张三

1.3 调用超级数组和超级链表实现栈

前面在泛型我们写了可实现增删查改的泛型超级数组和泛型超级链表,所以可以直接调用来实现栈

泛型超级数组和链表:https://www.cnblogs.com/TSCCG/p/14783226.html

主类:
package stack;

import polymorphic.SuperArray;

/**
 * @Author: TSCCG
 * @Date: 2021/5/21
 */
public class SuperStack<T> {
    Super<T> su = new SuperArray<>();
//    Super<T> su = new SuperLink<>();
    /**
     * 1.压栈方法
     * @param data
     */
    public void push(T data) {
        su.add(data);
        System.out.println("压栈" + data + "成功,栈帧指向" + (su.size() - 1));
    }
    /**
     * 2.弹栈方法
     * @return
     */
    public T pop() {
        if (su.size() >= 1) {
            T temp = su.get(su.size() - 1);
            su.delete(su.size() - 1);
            return temp;
        }
        return null;
    }
}

测试类:
import stack.SuperStack;

/**
 * @author: TSCCG
 * @date: 2021/5/21
 */
public class Test {
    public static void main(String[] args) {
        SuperStack<Object> stack = new SuperStack<>();
        stack.push("张三");
        stack.push("李四");
        stack.push("王五");
        stack.push("赵六");
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
        System.out.println("弹出了:" + stack.pop());
    }
}

结果:

压栈张三成功,栈帧指向0
压栈李四成功,栈帧指向1
压栈王五成功,栈帧指向2
压栈赵六成功,栈帧指向3
弹出了:赵六
弹出了:王五
弹出了:李四
弹出了:张三
弹出了:null

2. 队列

队列(queue)是一种先进先出(FIFO)的集合类型,即先添加的数据会先被删除。

类似排队进场,一个口进,一个口出。

05队列入队01.PNG 06队列入队02.PNG 07队列出队01.PNG 08队列出队02.PNG

调用超级数组和超级链表实现队列:

主类:
package queue;

import polymorphic.SuperArray;

/**
 * @author: TSCCG
 * @date: 2021/5/21
 */
public class SuperQueue<T>{
    Super<T> su = new SuperArray<>();
//    Super<T> su = new SuperLink<>();
    /**
     * 进栈方法
     * @param data
     * 进栈的数据
     */
    public void push(T data) {
        su.add(data);
        System.out.println("压栈" + data + "成功,栈帧指向" + (su.size() - 1));
    }

    /**
     * 出队方法
     * @return
     * 返回出队的数
     */
    public T pop() {
        if (su.size() >= 1) {
            T temp = su.get(0);
            su.delete(0);
            return temp;
        }
        return null;
    }
}
测试类:
import queue.SuperQueue;

/**
 * @author: TSCCG
 * @date: 2021/5/21
 */
public class Test {
    public static void main(String[] args) {
        SuperQueue<Object> stack = new SuperQueue<>();
        stack.push("张三");
        stack.push("李四");
        stack.push("王五");
        stack.push("赵六");
        System.out.println(stack.pop() + "出队了");
        System.out.println(stack.pop() + "出队了");
        System.out.println(stack.pop() + "出队了");
        System.out.println(stack.pop() + "出队了");
        System.out.println(stack.pop() + "出队了");
    }
}

结果:

压栈张三成功,栈帧指向0
压栈李四成功,栈帧指向1
压栈王五成功,栈帧指向2
压栈赵六成功,栈帧指向3
张三出队了
李四出队了
王五出队了
赵六出队了
null出队了
posted @ 2021-05-22 00:13  TSCCG  阅读(57)  评论(0编辑  收藏  举报