【数据结构】栈与队列

1.栈的定义

  • 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表。通常称插入、删除的这一端为栈顶(Top),另一端称为栈底(Bottom)。

  • 表中没有元素时称为空栈。

  • 栈为后进先出(Last In First Out)的线性表,简称为LIFO表。

  • 栈的修改是按后进先出的原则进行。每次删除(退栈)的总是当前栈中”最新”的元素,即最后插入(进栈)的元素,而最先插入的是被放在栈的底部,要到最后才能删除。

图解

【数据结构】栈与队列_第1张图片

2.用栈实现链表

public class StackLinked {
    private class Node{
        public int getData() {
            return data;
        }

        public void setData(int data) {
            this.data = data;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }

        private int data;
        private Node next;

        public Node(int data,Node next){
            this.data = data;
            this.next = next;
        }
    }

    private Node head;
    private int size = 0;

    //入栈
    public void push (int data) {
        Node node = new Node(data, null);
        if (null == this.head) {
            this.head = node;
            size++;
            return;
        } else {
            node.setNext(head);
            head = node;
        }
        size++;
    }

    //出栈
    public void pop(){
        if (size == 0) {
            System.out.println("队列为空!");
            return;
        }
        Node temp = head;
        head = head.getNext();
        size--;
        System.out.println(temp.getData());
    }

    //判断栈是否为空
    public boolean isEmpty(){
        if (head == null) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        StackLinked stack = new StackLinked();
        stack.push(3);
        stack.push(4);
        stack.push(9);
        stack.push(6);

        stack.pop();
        stack.pop();
        stack.pop();
        stack.pop();

        System.out.println(stack.isEmpty());
    }
}

输出结果

6
9
4
3
true

3.用栈实现数组

public class ArrayStack {
    private int size;
    int[] arr = new int[5];
    int top = -1;

    public ArrayStack(int size){
        this.size = size;
    }

    public void push(int... data){
        for (int a : data) {
            if (top + 1 == size) {
                System.out.println("stack is full");
                continue;
            }
            ++top;
            arr = data;
        }
    }

    public int pop() {
        if (-1 == top) {
            System.out.println("栈为空!");
        }
        return arr[top--];
    }

    public void print() {
        for (int i = size-1; i>=0; i--) {
            System.out.println(arr[i]);
        }
    }

    public static void main(String[] args) {
        ArrayStack stack = new ArrayStack(5);
        stack.push(5,9,3,2,6);

        stack.print();

        System.out.println("pop: "+stack.pop());
        System.out.println("pop: "+stack.pop());
        System.out.println("pop: "+stack.pop());
        System.out.println("pop: "+stack.pop());
        System.out.println("pop: "+stack.pop());

    }
}

输出结果

6
2
3
9
5
pop: 6
pop: 2
pop: 3
pop: 9
pop: 5

4.队列的定义

  • 队列( queue ) 是只允许在-端进行插入操作,而在另-端进行删除操作的线性表。

  • 队列是一种先进先出( First 10 First Out) 的线性衰,简称FIFO 。允许插入的一端称为队尾,允许删除的一端称为队头。

图解:

【数据结构】栈与队列_第2张图片

5.循环队列

public class LoopQueue {
    private int DEFAULT_SIZE = 10;

    private int capacity;//保存数组的长度

    private Object[] elementData;//定义一个数组用于保存循环队列的元素

    private int front = 0;//队头

    private int rear = 0;//队尾

    //以默认数组长度创建空循环队列
    public LoopQueue() {
        capacity = DEFAULT_SIZE;
        elementData = new Object[capacity];
    }

    //以一个初始化元素来创建循环队列
    public LoopQueue(T element) {
        this();
        elementData[0] = element;
        rear++;
    }

    //以指定循环队列中第一个元素和指定长度的数组来创建循环队列
    public LoopQueue(T element, int initSize) {
        this.capacity = initSize;
        elementData = new Object[capacity];
        elementData[0] = element;
        rear++;
    }

    //获取循环队列的大小
    public int size() {
        if (isEmpty()) {
            return 0;
        }
        return rear > front ? rear - front : capacity - (front - rear);
    }

    //插入队列
    public void add(T element) {
        if (rear == front && elementData[front] != null) {
            throw new IndexOutOfBoundsException("队列已满的异常");
        }
        elementData[rear++] = element;
        //如果rear已经到头,那就转头
        rear = rear == capacity ? 0 : rear;
    }

    //移除队列
    public T remove() {
        if (isEmpty()) {
            throw new IndexOutOfBoundsException("空队列异常");
        }
        //保留队列的rear端的元素的值
        T oldValue = (T) elementData[front];
        //释放队列的front端的元素
        elementData[front++] = null;
        //如果front已经到头,那就转头
        front = front == capacity ? 0 : front;
        return oldValue;
    }

    //返回队列顶元素,但不删除队列顶元素
    public T element() {
        if (isEmpty()) {
            throw new IndexOutOfBoundsException("空队列异常");
        }
        return (T) elementData[front];
    }

    //判断循环队列是否为空队列
    public boolean isEmpty() {
        //rear==front且rear处的元素为null
        return rear == front && elementData[rear] == null;
    }

    //清空循环队列
    public void clear() {
        //将底层数组所有元素赋为null
        Arrays.fill(elementData, null);
        front = 0;
        rear = 0;
    }

    public String toString() {
        if (isEmpty()) {
            return "[]";
        } else {
            //如果front < rear,有效元素就是front到rear之间的元素
            if (front < rear) {
                StringBuilder sb = new StringBuilder("[");
                for (int i = front; i < rear; i++) {
                    sb.append(elementData[i].toString() + ", ");
                }
                int len = sb.length();
                return sb.delete(len - 2, len).append("]").toString();
            }
            //如果front >= rear,有效元素为front->capacity之间、0->rear之间的
            else {
                StringBuilder sb = new StringBuilder("[");
                for (int i = front; i < capacity; i++) {
                    sb.append(elementData[i].toString() + ", ");
                }
                for (int i = 0; i < rear; i++) {
                    sb.append(elementData[i].toString() + ", ");
                }
                int len = sb.length();
                return sb.delete(len - 2, len).append("]").toString();
            }
        }
    }

    public static void main(String[] args) {
        LoopQueue queue = new LoopQueue("aaaa", 3);
        //添加两个元素
        queue.add("bbbb");
        queue.add("cccc");
        //此时队列已满
        System.out.println(queue);
        //删除一个元素后,队列可以再多加一个元素
        queue.remove();
        System.out.println("删除一个元素后的队列:" + queue);
        //再次添加一个元素,此时队列又满
        queue.add("dddd");
        System.out.println(queue);
        System.out.println("队列满时的长度:" + queue.size());

    }
}

输出结果

[aaaa, bbbb, cccc]
删除一个元素后的队列:[bbbb, cccc]
[bbbb, cccc, dddd]
队列满时的长度:3



本人才疏学浅,若有错,请指出
谢谢!

你可能感兴趣的:(数据结构与算法)