Java数据结构

Stack源码分析

继承关系
class Stack<E> extends Vector<E>
  • Vector和ArryList的实现一样,底层是用数组实现。与ArrayList的区别在于方法增加了synchronized同步标记,保证了线程安全,但是降低了并发效率。
  • Stack 使用的数组实际上就是父类的Vector的数组
属性 Field
  • Stack没有自己的属性,用的都是父类Vector的属性
protected Object[] elementData; // 用于存放元素的数组
protected int elementCount; // 栈内的有效元素

/**
     * The amount by which the capacity of the vector is automatically
     * incremented when its size becomes greater than its capacity.  If
     * the capacity increment is less than or equal to zero, the capacity
     * of the vector is doubled each time it needs to grow.
     *
     * @serial
     */
protected int capacityIncrement;
构造方法 Constructor
Stack()
/**
 * 子类会默认调用父类无参构造,此时super()可不写。
 */
public Stack() {
}
/**
 * 调用有参构造,初始化数组size为10
 */
public Vector() {
    this(10);
}
/**
 * 调用双参构造
 */
public Vector(int initialCapacity) {
    this(initialCapacity, 0);
}
/**
 * 初始化数组和增长数
 */
public Vector(int initialCapacity, int capacityIncrement) {
    super();
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    this.elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
}
普通方法 Method
push(E):E
  • 入栈操作
/**
 * 调用父类Vector的方法给数组添加元素,并返回入栈的值
 */
public E push(E item) {
        addElement(item);

        return item;
    }
/**
 * 入栈,调用父类Vector的方法给数组添加元素,并返回入栈的值。修改次数++(属于AbstractList用于迭代器)
 * elementData为Vector内的数组,elementCount是数组当前最后一个元素的下一位的下标
 */
public synchronized void addElement(E obj) {
        modCount++;
        add(obj, elementData, elementCount);
    }
/**
 * 超过数组长度(初始为10)则先扩容,将元素放入数组,然后下标后移一位。elementData[0]是栈底元素
 */
private void add(E e, Object[] elementData, int s) {
        if (s == elementData.length)
            elementData = grow();
        elementData[s] = e;
        elementCount = s + 1;
    }

peek():E
  • 返回栈顶元素,但不弹出栈顶元素
/**
     * 先判断栈的大小,若栈为空则抛出异常;否则返回数组最后一个元素(栈顶元素)
     */
    public synchronized E peek() {
        int len = size();

        if (len == 0)
            throw new EmptyStackException();
        return elementAt(len - 1);
    }

/**
     * Returns the number of components in this vector.
     *
     * @return  the number of components in this vector
     */
    public synchronized int size() {
        return elementCount;
    }
pop():E
  • 弹出栈顶元素,并返回栈顶元素
/**
     * Removes the object at the top of this stack and returns that
     * object as the value of this function.
     *
     * @return  The object at the top of this stack (the last item
     *          of the {@code Vector} object).
     * @throws  EmptyStackException  if this stack is empty.
     */
    public synchronized E pop() {
        E       obj;
        int     len = size();

        obj = peek();
        removeElementAt(len - 1);

        return obj;
    }

/**
     * 删除数组最后一个元素
     */
    public synchronized void removeElementAt(int index) {
        if (index >= elementCount) {
            throw new ArrayIndexOutOfBoundsException(index + " >= " +
                                                     elementCount);
        }
        else if (index < 0) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
        int j = elementCount - index - 1;
        if (j > 0) {
            System.arraycopy(elementData, index + 1, elementData, index, j);
        }
        modCount++;
        elementCount--;
        elementData[elementCount] = null; /* to let gc do its work */
    }
empty():boolean
  • 判断栈是否为空
/**
     * Tests if this stack is empty.判断当前数组大小,即elementCount的值即可
     *
     * @return  {@code true} if and only if this stack contains
     *          no items; {@code false} otherwise.
     */
    public boolean empty() {
        return size() == 0;
    }
	
	public synchronized int size() {
        return elementCount;
    }
search(Object):int
  • 查找栈中的某个元素下标
   /**
     * lastIndexof方法,数组从后往前找第一个,即距离栈顶最近的第一个元素,距离栈顶的距离+1,栈顶则返回1;没找到则返回-1
     */
    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

        if (i >= 0) {
            return size() - i;
        }
        return -1;
    }

PriorityQueue源码分析

继承关系
public class PriorityQueue<E> extends AbstractQueue<E>
    
public abstract class AbstractQueue<E>
    extends AbstractCollection<E>
    implements Queue<E>
  • 继承抽象队列类,实现了队列接口
属性 Field
    private static final int DEFAULT_INITIAL_CAPACITY = 11;

    /**
     * Priority queue represented as a balanced binary heap: the two
     * children of queue[n] are queue[2*n+1] and queue[2*(n+1)].  The
     * priority queue is ordered by comparator, or by the elements'
     * natural ordering, if comparator is null: For each node n in the
     * heap and each descendant d of n, n <= d.  The element with the
     * lowest value is in queue[0], assuming the queue is nonempty.
     */
    transient Object[] queue; // non-private to simplify nested class access

    /**
     * The number of elements in the priority queue.
     */
    int size;

    /**
     * The comparator, or null if priority queue uses elements'
     * natural ordering.
     */
    private final Comparator<? super E> comparator;

    /**
     * The number of times this priority queue has been
     * <i>structurally modified</i>.  See AbstractList for gory details.
     */
    transient int modCount;     // non-private to simplify nested class access
  • DEFAULT_INITIAL_CAPACITY:队列默认大小,初始化未指定队列大小时用此数
  • queue:用数组来存储元素,实际上是一个小根堆。最小的元素在 queue[0]
  • size:队列大小
  • comparator:用户可自定义比较器
  • modCount:修改次数
构造方法 Constructor
public PriorityQueue() {
        this(DEFAULT_INITIAL_CAPACITY, null);
    }
public PriorityQueue(int initialCapacity) {
        this(initialCapacity, null);
    }
public PriorityQueue(Comparator<? super E> comparator) {
        this(DEFAULT_INITIAL_CAPACITY, comparator);
    }
public PriorityQueue(int initialCapacity,
                         Comparator<? super E> comparator) {
        // Note: This restriction of at least one is not actually needed,
        // but continues for 1.5 compatibility
        if (initialCapacity < 1)
            throw new IllegalArgumentException();
        this.queue = new Object[initialCapacity];
        this.comparator = comparator;
    }
  • 主要是调用有两个参数的构造方法,传入队列初始大小值和比较器;否则使用默认大小值以及自然排序
public PriorityQueue(Collection<? extends E> c){
        if (c instanceof SortedSet<?>) {
            SortedSet<? extends E> ss = (SortedSet<? extends E>) c;
            this.comparator = (Comparator<? super E>) ss.comparator();
            initElementsFromCollection(ss);
        }
        else if (c instanceof PriorityQueue<?>) {
            PriorityQueue<? extends E> pq = (PriorityQueue<? extends E>) c;
            this.comparator = (Comparator<? super E>) pq.comparator();
            initFromPriorityQueue(pq);
        }
        else {
            this.comparator = null;
            initFromCollection(c);
        }
    }
public PriorityQueue(PriorityQueue<? extends E> c)
public PriorityQueue(SortedSet<? extends E> c)
  • 通过传入集合来构造优先队列,若集合实现了SortedSet接口或者集合原本就是PriorityQueue,则新创建的PriorityQueue使用参数集合中原有的Comparator,否则使用自然排序。
普通方法 Method
add(E):boolean
  • 直接调用offer方法
offer(E):boolean
public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        siftUp(i, e);
        size = i + 1;
        return true;
    }
  • 向PriorityQueue中插入一个元素,入队。重点在于队列的调整(堆化)siftUp
// 假设刚插入的x放在数组的最后一个地方,向上找其父节点和祖先节点,并按照大小放在合适的地方
    private static <T> void siftUpUsingComparator(
        int k, T x, Object[] es, Comparator<? super T> cmp) {
        while (k > 0) {
            int parent = (k - 1) >>> 1; // 父节点数组下标
            Object e = es[parent];
            if (cmp.compare(x, (T) e) >= 0) // 入队的 X 比父节点元素“大”则可退出
                break;
            es[k] = e;
            k = parent;
        }
        es[k] = x; // 插入元素
    }
  • 使用队列定义好的Comparator或者元素的自然排序来调整优先队列,使得最“小”的元素始终在堆顶queue[0]
peek():E
public E peek() {
    return (E) queue[0];
}
  • 返回堆顶元素,但是不从堆中删除该元素
poll():E
public E poll() {
    final Object[] es;
    final E result;

    if ((result = (E) ((es = queue)[0])) != null) {
        modCount++;
        final int n;
        final E x = (E) es[(n = --size)];
        es[n] = null;
        if (n > 0) {
            final Comparator<? super E> cmp;
            if ((cmp = comparator) == null)
                siftDownComparable(0, x, es, n);
            else
                siftDownUsingComparator(0, x, es, n, cmp);
        }
    }
    return result;
}
  • 返回并从堆中删除栈顶元素,重点在向下调整
// 可以理解为去掉堆顶元素后,将堆中最后一个元素重新offer(add)
private static <T> void siftDownUsingComparator(
        int k, T x, Object[] es, int n, Comparator<? super T> cmp) {
        // assert n > 0;
        int half = n >>> 1;
        while (k < half) { // 向下找到合适的位置
            int child = (k << 1) + 1;
            Object c = es[child];
            int right = child + 1;
            // 找到左右孩子中较小的那一个
            if (right < n && cmp.compare((T) c, (T) es[right]) > 0)
                c = es[child = right];
            // 和当前要放的元素进行比较
            if (cmp.compare(x, (T) c) <= 0)
                break;
            es[k] = c;
            k = child;
        }
    // 插入元素
        es[k] = x;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值