Deque and RandomizedQueues (双端队列和随机化队列)

泛型双端队列和随机队列

参考了5262yzu013685323的博客,感谢


  1. Java泛型

    - Java不允许创建泛型数组实例,需要强制类型转换:泛型采用擦除(Erasure)实现,运行时类型参数会被擦掉(实际元素都是Object),导致数组赋值时,类型产生错误。
    error
    但是java可以强制转换原生类型,即可以声明一个泛型数组的引用:(T [ ])

  2. 迭代器

    - 接口iterable张小琦介绍了iterable和iterator的区别。简单地说,客户端遍历所有元素,但不关心迭代器的内部实现。

    Iterator模式是用于遍历集合类的标准访问方法。它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构。

    - 接口iterator:实现iterable接口,可根据客户端需要的准则在内部类中继承的iterator接口并设计方法。调用iterator()方法时,返回内部类的实例,完成遍历功能。主要方法hasNext(), next()

  3. 数组实现栈结构

    - 游离:pop() 类型的操作中,避免 return s[–n] 的使用。此时该元素已经出栈,然而内存中仍有其指针(旧元素的指针),不能充分利用内存。采用如下方式:

    item = s[--n]
    s[n] = null
    return item

    - 可变的数组大小:反复倍增(repeat doubling)。一种合理的方法:当数组满,数组大小翻倍并copy数组所有元素。当数组减小到长度的 1/4 1 / 4 ,减半数组长度。


Codes
Deque 用链表结构
import java.util.Iterator;
import java.util.NoSuchElementException;

public class Deque<Item> implements Iterable<Item> {
    private int n;
    private Node first;
    private Node last;

    // helper linked list class
    private class Node {
        private Item item;
        private Node next;
        private Node prev;
    }

    public Deque() {
        first = null;
        last = first;
        n = 0;
    }

    public boolean isEmpty() {
        return n == 0;
    }

    public int size() {
        return n;
    }

    public void addFirst(Item item) {
        if (item == null)
            throw new IllegalArgumentException();
        Node oldfirst = first;
        first = new Node();
        first.item = item;
        first.prev = null;
        if (isEmpty()) {
            last = first;
            first.next = null;
        } else {
            first.next = oldfirst;
            oldfirst.prev = first;
        }
        n++;
    }

    public void addLast(Item item) {
        if (item == null)
            throw new IllegalArgumentException();
        Node oldlast = last;
        last = new Node();
        last.item = item;
        last.next = null;
        if (isEmpty()) {
            first = last;
            last.prev = null;
        } else {
            last.prev = oldlast;
            oldlast.next = last;
        }
        n++;
    }

    public Item removeFirst() {
        if (isEmpty())
            throw new NoSuchElementException();
        Item item = first.item;
        first = first.next;
        n--;
        if (isEmpty()) last = first = null;
        else first.prev = null;
        return item;
    }

    public Item removeLast() {
        if (isEmpty())
            throw new NoSuchElementException();
        Item item = last.item;
        last = last.prev;
        n--;
        if (isEmpty()) last = first = null;
        else last.next = null;
        return item;
    }

    public Iterator<Item> iterator() {
        return new DequeIterator();
    }

    private class DequeIterator implements Iterator<Item> {
        private Node current = first;

        public boolean hasNext() {
            return current != null;
        }

        public boolean hasPre() {
            return current != null;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }

        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            Item item = current.item;
            current = current.next;
            return item;
        }
    }
}

RandomizedQueue 采用数组结构
import edu.princeton.cs.algs4.StdRandom;
import java.util.Iterator;
import java.util.NoSuchElementException;

public class RandomizedQueue<Item> implements Iterable<Item> {
    private Item[] s;
    private int n = 0;

    public RandomizedQueue() {
        s = (Item[]) new Object[1];
    }

    private void resize(int capacity) {
        Item[] copy = (Item[]) new Object[capacity];
        for (int i = 0; i < n; i++)
            copy[i] = s[i];
        s = copy;
    }

    public boolean isEmpty() {
        return n == 0;
    }

    public int size() {
        return n;
    }

    public void enqueue(Item item) {
        if (item == null) {
            throw new IllegalArgumentException();
        }
        if (n == s.length) resize(2 * s.length);
        s[n++] = item;
    }

    public Item dequeue() {
        if (isEmpty()) throw new NoSuchElementException();
        int ranId = StdRandom.uniform(n);
        Item item = s[ranId];
        s[ranId] = s[n-1];
        s[--n] = null;
        if (n > 0 && n == s.length / 4) resize(s.length / 2);
        return item;
    }

    public Item sample() {
        if (isEmpty()) throw new NoSuchElementException();
        int id = StdRandom.uniform(n);
        return s[id];
    }

    public Iterator<Item> iterator() {
        return new RandQueIterator();
    }

    private class RandQueIterator implements Iterator<Item> {
        private final int[] randomIndex = StdRandom.permutation(n);
        private int i = 0;

        public boolean hasNext() { return i < n; }
        public void remove() { throw new UnsupportedOperationException(); }
        public Item next() {
            if (!hasNext()) throw new NoSuchElementException();
            return s[randomIndex[i++]];
        }
    }
}

这次的练习对java泛型和迭代器有了更好的认识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值