数据结构与算法(队列)

数据结构与算法

队列

是以顺序的方式维护的一组数据集合,在一端添加数据,从另一端移除数据,添加的一端为尾,移除的一端为头。

可分别基于链表、环形数组实现,相关代码,可在我的码云上查看;

案例:

自定义队列接口

// (先进先出)
public interface Queue<E> {

    // 向队列添加元素
    boolean offer(E e);

    // 向队列移除元素
    E pool();

    // 从队列头获取值,并不移除
    E peek();

    // 检查队列是否为空,true就是空
    boolean isEmpty();

    // 检查队列是否满了,true就是满了
    boolean isFull();

}

基于环形数组

// 队列 - 基于数组(环形数组)
// 下标计算公式:(开始下标 + 步数) % 数组长度 = 后移后的下标
// 优质算法:下标 & 数组长度
public class Array4Queue<E> implements Queue<E>, Iterable<E> {

    private int head = 0;
    private int tail = 0;
    private E[] arr = null;

    // 数组容量-永远是2的幂次方
    @SuppressWarnings("all")
    public Array4Queue(int num) {
        num -= 1;
        num |= num >> 1;
        num |= num >> 2;
        num |= num >> 4;
        num |= num >> 8;
        num |= num >> 16;
        num += 1;
        arr = (E[]) new Object[num];
    }

    // 向队列添加元素
    @Override
    public boolean offer(E e) {
        if (isFull()) {
            return false;
        }
        arr[tail & arr.length - 1] = e;
        tail++;
        return true;
    }

    // 向队列移除元素
    @Override
    public E pool() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[head & arr.length - 1];
        head++;
        return e;
    }

    // 从队列头获取值,并不移除
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[head & arr.length - 1];
        return e;
    }

    // 检查队列是否为空,true就是空
    @Override
    public boolean isEmpty() {
        return tail == head;
    }

    // 检查队列是否满了,true就是满了
    @Override
    public boolean isFull() {
        return tail - head == arr.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int n = head;
            @Override
            public boolean hasNext() {
                return n != tail;
            }
            @Override
            public E next() {
                E e = arr[n & arr.length - 1];
                n++;
                return e;
            }
        };
    }
    
}

基于链表

// 队列 - 基于链表实现
public class LinkListQueue<E> implements Queue<E>, Iterable<E> {

    static class Node<E> {
        private E value;
        private Node<E> next;
        public Node(E value, Node<E> next) {
            this.value = value;
            this.next = next;
        }
    }

    private Node<E> head = new Node<>(null, null);
    private Node<E> tail = head;
    private int size = 0;
    private int num = Integer.MAX_VALUE;

    public LinkListQueue() {

    }

    public LinkListQueue(int num) {
        this.num = num;
    }

    {
        head.next = head;
    }

    // 向队列添加元素
    // head null 1 null
    // tail 1 null
    @Override
    public boolean offer(E e) {
        if (isFull()) {
            return false;
        }
        Node<E> node = new Node<>(e, head);
        tail.next = node;
        tail = node;
        size++;
        return true;
    }

    // 向队列移除元素
    @Override
    public E pool() {
        if (isEmpty()) {
            return null;
        }
        Node<E> first = head.next;
        head.next = first.next;
        if (tail == first) {
            tail = head;
        }
        size--;
        return first.value;
    }

    // 从队列头获取值,并不移除
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        Node<E> first = head.next;
        return first.value;
    }

    // 检查队列是否为空,true就是空
    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    // 检查队列是否满了,true就是满了
    @Override
    public boolean isFull() {
        return size >= num;
    }

    // 遍历
    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> n = head.next;
            @Override
            public boolean hasNext() {
                return n != head;
            }
            @Override
            public E next() {
                E value = n.value;
                n = n.next;
                return value;
            }
        };
    }

}

双端队列

两端都可以添加、删除,也可分别基于链表、环形数组实现;

案例:

自定义队列接口

public interface DQueue<E> {

    // 向头部添加
    boolean offerFirst(E e);

    // 向尾部添加
    boolean offerLast(E e);

    // 从头部移除元素
    E poolFirst();

    // 从尾部移除元素
    E poolLast();

    // 从头部获取值,并不移除
    E peekFirst();

    // 从尾部获取值,并不移除
    E peekLast();

    // 检查队列是否为空,true就是空
    boolean isEmpty();

    // 检查队列是否满了,true就是满了
    boolean isFull();

}

基于数组

// 双端队列 - 基于-环形数组的队列
public class ArrayDQueue<E> implements DQueue<E>, Iterable<E> {

    E[] arr;
    private int head;
    private int tail;

    public ArrayDQueue(int num) {
        arr = (E[]) new Object[num + 1];
    }

    // 加法
    private int iec(int i) {
        if (i + 1 >= arr.length) {
            return 0;
        }
        return i + 1;
    }

    // 减法
    private int dec(int i) {
        if (i - 1 < 0) {
            return arr.length - 1;
        }
        return i - 1;
    }

    @Override
    public boolean offerFirst(E e) {
        if (isFull()) {
            return false;
        }
        head = dec(head);
        arr[head] = e;
        return true;
    }

    @Override
    public boolean offerLast(E e) {
        if (isFull()) {
            return false;
        }
        arr[tail] = e;
        tail = iec(tail);
        return true;
    }

    @Override
    public E poolFirst() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[head];
        arr[head] = null;
        head = iec(head);
        return e;
    }

    @Override
    public E poolLast() {
        if (isEmpty()) {
            return null;
        }
        tail = dec(tail);
        E e = arr[tail];
        arr[tail] = null;
        return e;
    }

    @Override
    public E peekFirst() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[head];
        return e;
    }

    @Override
    public E peekLast() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[dec(tail)];
        return e;
    }

    @Override
    public boolean isEmpty() {
        return head == tail;
    }

    @Override
    public boolean isFull() {
        if (head > tail) {
            return head - tail == 1;
        } else if (head < tail) {
            return tail - head == arr.length - 1;
        } else {
            return false;
        }
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int n = head;
            @Override
            public boolean hasNext() {
                return n != tail;
            }
            @Override
            public E next() {
                E e = arr[n];
                n = iec(n);
                return e;
            }
        };
    }

}

优先级队列

它是一端进,另一端出,按优先级进行出队,也是优先级高者先出队列;

自定义队列接口

public interface Priority {
    // 返回优先级,数值越大越高
    int priority();
}

基于数组(无序数组)

// 优先级队列 - 基于 数组(无序数组) - 数组存入的元素不是按优先级排序的,是无序的
@SuppressWarnings("all")
public class PriorityQueue1<E extends Priority> implements Queue<E> {

    Priority[] arr;
    int size = 0;

    public PriorityQueue1(int num) {
        arr = new Priority[num];
    }

    @Override
    public boolean offer(E e) {
        if (isFull()) {
            return false;
        }
        arr[size++] = e;
        return true;
    }

    @Override
    public E pool() {
        if (isEmpty()) {
            return null;
        }
        int i = getMaxIndex();
        E e = (E) arr[i];
        arr[i] = null;
        // 重新排序 , 后面的元素移动到前面
        if (i < size - 1) {
            System.arraycopy(arr, i + 1, arr, i, size - 1 - i);
        }
        size--;
        return e;
    }

    // 获取最大下标
    private int getMaxIndex() {
        int max = 0;
        for (int i = 1; i < size; i++) {
            if (arr[i].priority() > arr[max].priority()) {
                max = i;
            }
        }
        return max;
    }

    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        int i = getMaxIndex();
        E e = (E) arr[i];
        return e;
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public boolean isFull() {
        return size == arr.length;
    }
}

延迟队列

根据延时时间确定优先级;

并发非阻塞队列

队列空或者不满时不叫阻塞

// 阻塞队列 - 双锁实现 (添加不影响获取,获取不影响添加)
@SuppressWarnings("all")
public class BlockQueue<E> implements BlockingQueue<E> {

    E[] arr;
    int head;
    int tail;
    AtomicInteger size = new AtomicInteger();
    
    public BlockQueue(int num) {
        arr = (E[]) new Object[num];
    }

    Lock headLock = new ReentrantLock();
    Lock tailLock = new ReentrantLock();
    Condition headCon = headLock.newCondition();
    Condition tailCon = tailLock.newCondition();

    // 添加,没有返回值,如果队列满了,进行排队等待
    public void offer(E e) throws InterruptedException {
        int c;
        tailLock.lockInterruptibly();
        try {
            while (isFull()) {
                tailCon.await();
            }
            arr[tail] = e;
            if (++tail == arr.length) {
                tail = 0;
            }
            c = size.getAndIncrement();
            if (c + 1 < arr.length) {
                tailCon.signal();
            }
        } finally {
            tailLock.unlock();
        }
        if (c == 0) {
            headLock.lock();
            try {
                headCon.signal();
            } finally {
                headLock.unlock();
            }
        }
    }

    // 添加,超时不再等待(毫秒)
    public boolean offer(E e, long timeout) throws InterruptedException {
        int c;
        tailLock.lockInterruptibly();
        try {
            long t = TimeUnit.MILLISECONDS.toNanos(timeout);
            while (isFull()) {
                if (t < 0) {
                    return false; // 等待超时 - 不再等待,返回false,代表添加失败
                }
                t = tailCon.awaitNanos(t);
            }
            arr[tail] = e;
            if (++tail == arr.length) {
                tail = 0;
            }
            c = size.getAndIncrement();
            if (c + 1 < arr.length) {
                tailCon.signal();
            }
        } finally {
            tailLock.unlock();
        }
        if (c == 0) {
            headLock.lock();
            try {
                headCon.signal();
            } finally {
                headLock.unlock();
            }
        }
        return true;
    }

    // 移出一个元素,如果队列没有,进行阻塞等待添加
    public E pool() throws InterruptedException {
        int c;
        headLock.lockInterruptibly();
        E e;
        try {
            while (isEmpty()) {
                headCon.await();
            }
            e = arr[head];
            arr[head] = null;
            if (++head == arr.length) {
                head = 0;
            }
            c = size.getAndDecrement();
            if (c > 1) {
                headCon.signal();
            }
        } finally {
            headLock.unlock();
        }
        if (c == arr.length) {
            tailLock.lock();
            try {
                tailCon.signal();
            } finally {
                tailLock.unlock();
            }
        }
        return e;
    }

    public boolean isFull() {
        return size.get() == arr.length;
    }

    public String toString() {
        return "BlockQueue2{" +
                "arr=" + Arrays.toString(arr) +
                '}';
    }
}

并发阻塞队列

队列空删除阻塞,队列满时添加阻塞

是一种线性的数据结构,只能在一端进行添加数据和移除数据;其中一端是栈顶,另一端不能操作被称作栈低。

可分别基于链表、数组实现,相关代码,可在我的码云上查看;

案例:

自定义栈接口

// (先进后出)
public interface Stack<E> {

    // 向栈顶添加元素
    boolean push(E e);

    // 向栈顶移除元素
    E pol();

    // 从栈顶获取获取值,并不移除
    E peek();

    // 检查是否为空,true就是空
    boolean isEmpty();

    // 检查是否满了,true就是满了
    boolean isFull();

}

基于数组实现

public class ArrayStack<E> implements Stack<E>, Iterable<E> {

    E[] arr;
    int size = 0;

    @SuppressWarnings("all")
    public ArrayStack(int size) {
        arr = (E[]) new Object[size];
    }

    // 向栈顶添加元素
    @Override
    public boolean push(E e) {
        if (isFull()) {
            return false;
        }
        arr[size] = e;
        size++;
        return true;
    }

    // 向栈顶移除元素
    @Override
    public E pol() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[size - 1];
        size--;
        return e;
    }

    // 从栈顶获取获取值,并不移除
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        E e = arr[size - 1];
        return e;
    }

    // 检查是否为空,true就是空
    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    // 检查是否满了,true就是满了
    @Override
    public boolean isFull() {
        return size == arr.length;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            int n = size;
            @Override
            public boolean hasNext() {
                return n > 0;
            }
            @Override
            public E next() {
                E e = arr[n - 1];
                n--;
                return e;
            }
        };
    }

}

基于链表实现

public class LinkListStack<E> implements Stack<E>, Iterable<E> {

    static class Node<E> {
        private E value;
        private Node<E> next;
        public Node(E value, Node<E> next) {
            this.value = value;
            this.next = next;
        }
    }

    // 栈顶
    private Node<E> head = new Node<>(null, null);
    private int size = 0;
    private int num = 0;

    public LinkListStack(int num) {
        this.num = num;
    }

    // 向栈顶添加元素
    @Override
    public boolean push(E e) {
        if (isFull()) {
            return false;
        }
        Node<E> node = new Node<>(e, head.next);
        head.next = node;
        size++;
        return true;
    }

    // 向栈顶移除元素
    @Override
    public E pol() {
        if (isEmpty()) {
            return null;
        }
        Node<E> node = head.next;
        head.next = node.next;
        size--;
        return node.value;
    }

    // 从栈顶获取获取值,并不移除
    @Override
    public E peek() {
        if (isEmpty()) {
            return null;
        }
        Node<E> node = head.next;
        return node.value;
    }

    // 检查是否为空,true就是空
    @Override
    public boolean isEmpty() {
//        return head.next == null;
        return size == 0;
    }
   
    // 检查是否满了,true就是满了
    @Override
    public boolean isFull() {
        return size == num;
    }

    @Override
    public Iterator<E> iterator() {
        return new Iterator<E>() {
            Node<E> node = head.next;
            @Override
            public boolean hasNext() {
                return node != null;
            }
            @Override
            public E next() {
                E value = node.value;
                node = node.next;
                return value;
            }
        };
    }
 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值