排序算法与数据结构复习总结

查找

Arrays工具类中二分查找
private static int binarySearch0(int[] a, int fromIndex, int toIndex,
                                 int key) {
    int low = fromIndex;
    int high = toIndex - 1;

    while (low <= high) {
        int mid = (low + high) >>> 1;
        int midVal = a[mid];

        if (midVal < key)
            low = mid + 1;
        else if (midVal > key)
            high = mid - 1;
        else
            return mid; // key found
    }
    return -(low + 1);  // key not found.
}

时间复杂度

排序

冒泡排序
public static void bubbleSort(int arr[]) {
    for(int i =0 ; i<arr.length-1 ; i++) { 
        for(int j=0 ; j<arr.length-1-i ; j++) {  
            if(arr[j]>arr[j+1]) {
                int temp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }    
    }
}
选择排序
public static void selectionSort(int[] arr){
    //需要比较的次数,数组长度减一
    for(int i = 0; i < arr.length - 1; i++){
        //先假设每次循环时,最小数的索引为i
        int minIndex = i;
        //每一个元素都和剩下的未排序的元素比较
        for(int j = i + 1; j < arr.length; j++){
            if(arr[j] < arr[minIndex]){//寻找最小数
                minIndex = j;//将最小数的索引保存
            }
        }
        //经过一轮循环,就可以找出第一个最小值的索引,然后把最小值放到i的位置
        swap(arr, i, minIndex);
    }
}

private static void swap(int[] arr, int i, int j) {
    int temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}
插入排序
public class Insertion {
    public static void sort(Comparable[] a) {
        //将a[]按升序排列
        int N=a.length;
        for (int i=1;i<N;i++) {
        //将a[i]插入到a[i-1],a[i-2],a[i-3]……之中
            for(int j=i; j>0 && (a[j].compareTo(a[j-1])<0);j--) {
                Comparable temp=a[j];
                a[j]=a[j-1];
                a[j-1]=temp;
            }
        }
    }
}
希尔排序
public void shellSort() {
    int gap = array.length;
    while (true) {    
        gap /= 2;   //增量每次减半    
        for (int i = 0; i < gap; i++) {        
            for (int j = i + gap; j < array.length; j += gap) {
            //这个循环里其实就是一个插入排序            int k = j - gap;            
                while (k >= 0 && array[k] > array[k+gap]) {
                    int temp = array[k];
                    array[k] = array[k+gap];
                    array[k + gap] = temp;     
                    k -= gap;            
                }                
            }    
        }    
        if (gap == 1)        
            break;
    }
}
归并排序
public static int[] mergeSort(int[] nums, int l, int h) {
    if (l == h)
        return new int[] { nums[l] };
     
    int mid = l + (h - l) / 2;
    int[] leftArr = mergeSort(nums, l, mid); //左有序数组
    int[] rightArr = mergeSort(nums, mid + 1, h); //右有序数组
    int[] newNum = new int[leftArr.length + rightArr.length]; //新有序数组
     
    int m = 0, i = 0, j = 0; 
    while (i < leftArr.length && j < rightArr.length) {
        newNum[m++] = leftArr[i] < rightArr[j] ? leftArr[i++] : rightArr[j++];
    }
    while (i < leftArr.length)
        newNum[m++] = leftArr[i++];
    while (j < rightArr.length)
        newNum[m++] = rightArr[j++];
    return newNum;
}
快速排序
public static int[] qsort(int arr[],int start,int end) {        
    int pivot = arr[start];        
    int i = start;        
    int j = end;        
    while (i<j) {            
        while ((i<j)&&(arr[j]>pivot)) {            
            j--;            
        }            
        while ((i<j)&&(arr[i]<pivot)) {         
            i++;            
        }            
        if ((arr[i]==arr[j])&&(i<j)) {             
            i++;            
        } else {                
            int temp = arr[i];                
            arr[i] = arr[j];                
            arr[j] = temp;            
        }        
    }        
    if (i-1>start) arr=qsort(arr,start,i-1);       
    if (j+1<end) arr=qsort(arr,j+1,end);        
    return (arr);    
}    
 
public static void main(String[] args) {        
    int arr[] = new int[]{3,3,3,7,9,122344,4656,34,34,4656,5,6,7,8,9,343,57765,23,12321};        
    int len = arr.length-1;        
    arr=qsort(arr,0,len);        
    for (int i:arr) {            
        System.out.print(i+"\t");        
    }    
}

方式2

public <TextendsComparable<?superT>>
T[] quickSort(T[] targetArr,int start,int end)
{
    int i=start+1 , j=end;
    T key = targetArr[start];
    SortUtil<T> sUtil=new SortUtil<T>();
 
    if(start==end) return (targetArr);
 
 
    /** 
     *  从i++和j--两个方向搜索不满足条件的值并交换
     *  条件为:i++方向小于key,j--方向大于key
     */
    while(true) {
        while(targetArr[j].compareTo(key) > 0) j--;
        while(targetArr[i].compareTo(key) < 0 && i<j) i++;
        if(i>=j) break;
        sUtil.swap(targetArr,i,j);
        if(targetArr[i]==key) {
            j--;
        } else {
            i++;
        }
    }
 
    /*关键数据放到‘中间’*/
    sUtil.swap(targetArr,start,j);
    if(start<i-1) {
        this.quickSort(targetArr,start,i-1);
    }
    if(j+1<end) {
        this.quickSort(targetArr,j+1,end);
    }
    returntargetArr;
}

方式3

private<TextendsComparable<?superT>>
voidquickSort(T[]targetArr,intstart,intend) {
    inti=start,j=end;
    T key=targetArr[start];
 
    while(i<j) {
        /*按j--方向遍历目标数组,直到比key小的值为止*/
        while(j>i&&targetArr[j].compareTo(key)>=0){
            j--;
        }
        if(i<j) {
            /*targetArr[i]已经保存在key中,可将后面的数填入*/
            targetArr[i]=targetArr[j];
            i++;
        }
        /*按i++方向遍历目标数组,直到比key大的值为止*/
        while(i<j&&targetArr[i].compareTo(key)<=0)
        /*此处一定要小于等于零,假设数组之内有一亿个1,0交替出现的话,而key的值又恰巧是1的话,那么这个小于等于的作用就会使下面的if语句少执行一亿次。*/
        {
            i++;
        }
        if(i<j) {
            /*targetArr[j]已保存在targetArr[i]中,可将前面的值填入*/
            targetArr[j]=targetArr[i];
            j--;
        }
    }
    /*此时i==j*/
    targetArr[i]=key;//应加判断
 
    /*递归调用,把key前面的完成排序*/
    this.quickSort(targetArr,start,i-1);
 
    /*递归调用,把key后面的完成排序*/
    this.quickSort(targetArr,j+1,end);
    //两个递归应加判断
}

堆排序
    /**
    * 选择排序-堆排序
    * @param array 待排序数组
    * @return 已排序数组
    */
    public static int[] heapSort(int[] array) {
        //这里元素的索引是从0开始的,所以最后一个非叶子结点array.length/2 - 1
        for (int i = array.length / 2 - 1; i >= 0; i--) {  
            adjustHeap(array, i, array.length);  //调整堆
        }
  
        // 上述逻辑,建堆结束
        // 下面,开始排序逻辑
        for (int j = array.length - 1; j > 0; j--) {
            // 元素交换,作用是去掉大顶堆
            // 把大顶堆的根元素,放到数组的最后;换句话说,就是每一次的堆调整之后,都会有一个元素到达自己的最终位置
            swap(array, 0, j);
            // 元素交换之后,毫无疑问,最后一个元素无需再考虑排序问题了。
            // 接下来我们需要排序的,就是已经去掉了部分元素的堆了,这也是为什么此方法放在循环里的原因
            // 而这里,实质上是自上而下,自左向右进行调整的
            adjustHeap(array, 0, j);
        }
        return array;
    }
  
    /**
    * 整个堆排序最关键的地方
    * @param array 待组堆
    * @param i 起始结点
    * @param length 堆的长度
    */
    public static void adjustHeap(int[] array, int i, int length) {
        // 先把当前元素取出来,因为当前元素可能要一直移动
        int temp = array[i];
        for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {  //2*i+1为左子树i的左子树(因为i是从0开始的),2*k+1为k的左子树
            // 让k先指向子节点中最大的节点
            if (k + 1 < length && array[k] < array[k + 1]) {  //如果有右子树,并且右子树大于左子树
                k++;
            }
            //如果发现结点(左右子结点)大于根结点,则进行值的交换
            if (array[k] > temp) {
                swap(array, i, k);
                // 如果子节点更换了,那么,以子节点为根的子树会受到影响,所以,循环对子节点所在的树继续进行判断
                    i  =  k;
                        } else {  //不用交换,直接终止循环
                break;
            }
        }
    }
  
    /**
    * 交换元素
    * @param arr
    * @param a 元素的下标
    * @param b 元素的下标
    */
    public static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
计数排序
//针对c数组的大小,优化过的计数排序
publicclassCountSort{
    publicstaticvoidmain(String[]args){
      //排序的数组
        int a[]={100,93,97,92,96,99,92,89,93,97,90,94,92,95};
        int b[]=countSort(a);
        for(inti:b){
           System.out.print(i+"");
        }
        System.out.println();
    }
    public static int[] countSort(int[]a){
        int b[] = new int[a.length];
        int max = a[0],min = a[0];
        for(int i:a){
            if(i>max){
                max=i;
            }
            if(i<min){
                min=i;
            }
        }//这里k的大小是要排序的数组中,元素大小的极值差+1
        int k=max-min+1;
        int c[]=new int[k];
        for(int i=0;i<a.length;++i){
            c[a[i]-min]+=1;//优化过的地方,减小了数组c的大小
        }
        for(int i=1;i<c.length;++i){
            c[i]=c[i]+c[i-1];
        }
        for(int i=a.length-1;i>=0;--i){
            b[--c[a[i]-min]]=a[i];//按存取的方式取出c的元素
        }
    return b;
    }
}
桶排序
public static void basket(int data[]) {
    int n=data.length;
    int bask[][]=new int[10][n];
    int index[]=new int[10];
    int max=Integer.MIN_VALUE;
    for(int i=0;i<n;i++){
        max=max>(Integer.toString(data[i]).length())?max:(Integer.toString(data[i]).length());
    }
    String str;
    for(int i=max-1;i>=0;i--) {
        for(int j=0;j<n;j++){
            str="";
            if(Integer.toString(data[j]).length()<max) {
            for(int k=0;k<max-Integer.toString(data[j]).length();k++){
                str+="0";
            }
            str+=Integer.toString(data[j]);
            bask[str.charAt(i)-'0'][index[str.charAt(i)-'0']++]=data[j];
        }
        int pos=0;
        for(int j=0;j<10;j++) {
            for(int k=0;k<index[j];k++) {
                data[pos++]=bask[j][k];
            }
        }
        for(intx=0;x<10;x++) index[x]=0;
    }
}

基数排序
public class RadixSort
{
    public static void sort(int[] number, int d) //d表示最大的数有多少位
    {
        intk = 0;
        intn = 1;
        intm = 1; //控制键值排序依据在哪一位
        int[][]temp = newint[10][number.length]; //数组的第一维表示可能的余数0-9
        int[]order = newint[10]; //数组order[i]用来表示该位是i的数的个数
        while(m <= d)
        {
            for(inti = 0; i < number.length; i++)
            {
                intlsd = ((number[i] / n) % 10);
                temp[lsd][order[lsd]] = number[i];
                order[lsd]++;
            }
            for(inti = 0; i < 10; i++)
            {
                if(order[i] != 0)
                    for(intj = 0; j < order[i]; j++)
                    {
                        number[k] = temp[i][j];
                        k++;
                    }
                order[i] = 0;
            }
            n *= 10;
            k = 0;
            m++;
        }
    }
    public static void main(String[] args)
    {
        int[]data =
        {73, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100};
        RadixSort.sort(data, 3);
        for(inti = 0; i < data.length; i++)
        {
            System.out.print(data[i] + "");
        }
    }
}

JDK DualPivotQuicksort双基准快速排序
时间复杂度

https://www.cnblogs.com/onepixel/articles/7674659.html

数据结构

栈的实现

链式实现
public class LinkedStack<E> {
    private Node<E> topNode;

    public LinkedStack() {
        topNode = null;
    }

    public void push(E e) {
        Node<E> newNode = new Node<>(e, topNode);
        topNode = newNode;
    }

    public E peek() {
        // isEmpty()
        return topNode.item;
    }

    public E pop() {
        E top = peek();
        //topNode != null
        topNode = topNode.next;
        return top;
    }

    private class Node<E> {
        private E item;
        private Node<E> next;

        Node(E item, Node<E> topNode) {
            this.item = item;
            next = topNode;
        }
    }
}
数组实现
public class ArrayStack<E> {
    private E[] stack;
    private int topIndex;
    private boolean initialized = false;
    private static final int DEFAULT_CAPACITY = 50;
    private static final int MAX_CAPACITY = 1000;
    
    public ArrayStack() {
        this(DEFAULT_CAPACITY);
    }
    
    public ArrayStack(int initCapacity) {
        //checkCapacity(initCapacity);
        E [] tempStack = (E[])new Object[initCapacity];
        stack = tempStack;
        topIndex = -1;
        initialized = true;
    }
    
    public void push(E item) {
        // checkInitialization()
        ensureCapacity();
        stack[topIndex + 1] = item;
        topIndex++;
    }
    
    private void ensureCapacity() {
        if(topIndex == stack.length - 1) {
            int newLength = 2 * stack.length;
            //checkCapacity(newLength)
            stack = Arrays.copyOf(stack, newLength);
        }
    }
    
    public E peek() {
        // checkInitialization()
        // isEmpty
        return stack[topIndex];
    }
    
    public E pop() {
        // checkInitialization()
        // isEmpty
        E top = stack[topIndex];
        stack[topIndex] = null;
        topIndex--;
        return pop();
    }
}
JDK继承vector实现的Stack源码
public
class Stack<E> extends Vector<E> {
    public Stack() {
    }

    public E push(E item) {
        addElement(item);

        return item;
    }

    public synchronized E pop() {
        E       obj;
        int     len = size();

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

        return obj;
    }

    public synchronized E peek() {
        int     len = size();

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

    public boolean empty() {
        return size() == 0;
    }

    public synchronized int search(Object o) {
        int i = lastIndexOf(o);

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


    private static final long serialVersionUID = 1224463164541339165L;
}

队列实现

链式队列实现
public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
    transient Node<E> first;
    transient Node<E> last;
    public LinkedList() {}
    
    private void linkFirst(E e) {
        final Node<E> f = first;
        final Node<E> newNode = new Node<>(null, e, f);
        first = newNode;
        if (f == null)
            last = newNode;
        else
            f.prev = newNode;
        size++;
        modCount++;
    }
    
    private E unlinkFirst(Node<E> f) {
        // assert f == first && f != null;
        final E element = f.item;
        final Node<E> next = f.next;
        f.item = null;
        f.next = null; // help GC
        first = next;
        if (next == null)
            last = null;
        else
            next.prev = null;
        size--;
        modCount++;
        return element;
    }
    
    void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }
    
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
    
    public boolean offer(E e) {
        return add(e);
    }
    
    public boolean add(E e) {
        linkLast(e);
        return true;
    }
    
    public E peek() {
        final Node<E> f = first;
        return (f == null) ? null : f.item;
    }
    
    public E poll() {
        final Node<E> f = first;
        return (f == null) ? null : unlinkFirst(f);
    }
数组队列实现
public class ArrayDeque<E> extends AbstractCollection<E>
                           implements Deque<E>, Cloneable, Serializable
{
    transient int head;
    transient int tail;
    
    public ArrayDeque() {
        elements = new Object[16];
    }
    
    public boolean offer(E e) {
        return offerLast(e);
    }
    
    public E poll() {
        return pollFirst();
    }
    
    public E peek() {
        return peekFirst();
    }

    public boolean offerLast(E e) {
        addLast(e);
        return true;
    }
    
    public void addLast(E e) {
        if (e == null)
            throw new NullPointerException();
        elements[tail] = e;
        if ( (tail = (tail + 1) & (elements.length - 1)) == head)
            doubleCapacity();
    }
    
    public E pollFirst() {
        int h = head;
        @SuppressWarnings("unchecked")
        E result = (E) elements[h];
        // Element is null if deque empty
        if (result == null)
            return null;
        elements[h] = null;     // Must null out slot
        head = (h + 1) & (elements.length - 1);
        return result;
    }
    
    public E peekFirst() {
        // elements[head] is null if deque empty
        return (E) elements[head];
    }
}

线性表实现

ArrayList
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    transient Object[] elementData;
    
    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
    
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }
}

迭代器实现

HashMap类中迭代器
    abstract class HashIterator {
        Node<K,V> next;        // next entry to return
        Node<K,V> current;     // current entry
        int expectedModCount;  // for fast-fail
        int index;             // current slot

        HashIterator() {
            expectedModCount = modCount;
            Node<K,V>[] t = table;
            current = next = null;
            index = 0;
            if (t != null && size > 0) { // advance to first entry
                do {} while (index < t.length && (next = t[index++]) == null);
            }
        }

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

        final Node<K,V> nextNode() {
            Node<K,V>[] t;
            Node<K,V> e = next;
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            if (e == null)
                throw new NoSuchElementException();
            if ((next = (current = e).next) == null && (t = table) != null) {
                do {} while (index < t.length && (next = t[index++]) == null);
            }
            return e;
        }

        public final void remove() {
            Node<K,V> p = current;
            if (p == null)
                throw new IllegalStateException();
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
            current = null;
            K key = p.key;
            removeNode(hash(key), key, null, false, false);
            expectedModCount = modCount;
        }
    }

    final class KeyIterator extends HashIterator
        implements Iterator<K> {
        public final K next() { return nextNode().key; }
    }

    final class ValueIterator extends HashIterator
        implements Iterator<V> {
        public final V next() { return nextNode().value; }
    }

    final class EntryIterator extends HashIterator
        implements Iterator<Map.Entry<K,V>> {
        public final Map.Entry<K,V> next() { return nextNode(); }
    }

散列

二叉查找树
public class BinaryNode<T> {
    private T data;
    private BinaryNode<T> leftChild;
    private BinaryNode<T> rightChild;

    public BinaryNode() {
        this(null);
    }

    public BinaryNode(T data) {
        this(data, null, null);
    }

    public BinaryNode(T data, BinaryNode<T> leftChild, BinaryNode<T> rightChild) {
        this.data = data;
        this.leftChild = leftChild;
        this.rightChild = rightChild;
    }

    public boolean hasLeftChild() {
        return leftChild != null;
    }

    public boolean isLeaf() {
        return (leftChild == null) && (rightChild == null);
    }

    public int getNumberOfNodes() {
        int leftNumber = 0;
        int rightNumber = 0;
        if (leftChild != null) {
            leftNumber = leftChild.getNumberOfNodes();
        }
        if(rightChild != null) {
            rightNumber = rightChild.getNumberOfNodes();
        }
        return 1 + leftNumber + rightNumber;
    }

    public int getHeight(BinaryNode<T> node) {
        int height = 0;
        if (node != null) {
            height = 1 + Math.max(getHeight(node.getLeftChild()), getHeight(node.getRightChild()));
        }
        return height;
    }

    public BinaryNode<T> copy() {
        BinaryNode<T> newRoot = new BinaryNode<>(data);
        if(leftChild != null) {
            newRoot.setLeftChild(leftChild.copy());
        }
        if(rightChild != null) {
            newRoot.setRightChild(rightChild.copy());
        }
        return newRoot;
    }

    public T getData() {
        return data;
    }

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

    public BinaryNode<T> getLeftChild() {
        return leftChild;
    }

    public void setLeftChild(BinaryNode<T> leftChild) {
        this.leftChild = leftChild;
    }

    public BinaryNode<T> getRightChild() {
        return rightChild;
    }

    public void setRightChild(BinaryNode<T> rightChild) {
        this.rightChild = rightChild;
    }
}

public class BinaryTree<T> {
    private BinaryNode<T> root;

    public BinaryTree() {
        root = null;
    }

    public BinaryTree(T rootData) {
        root = new BinaryNode<>(rootData);
    }

    public BinaryTree(T rootData, BinaryTree<T> leftTree, BinaryTree<T> rightTree) {
        privateSetTree(rootData, leftTree, rightTree);
    }

    public void setTree(T rootData) {
        root = new BinaryNode<>(rootData);
    }

    private void privateSetTree(T rootData, BinaryTree<T> leftTree, BinaryTree<T> rightTree) {
        root = new BinaryNode<>(rootData);
        if((leftTree != null) && !leftTree.isEmpty()) {
            root.setLeftChild(leftTree.root.copy());
        }

        if((rightTree != null) && !leftTree.isEmpty()) {
            root.setRightChild(rightTree.root.copy());
        }
    }

    private boolean isEmpty() {
        return root == null;
    }

    public int getHeight() {
        return root.getHeight(root);
    }

    public int getNumberOfNodes() {
        return root.getNumberOfNodes();
    }

    public void inOrderTraverse() {
        inOrderTraverse(root);
    }

    private void inOrderTraverse(BinaryNode<T> node) {
        if(node != null) {
            System.out.println(node.getData());
            inOrderTraverse(node.getLeftChild());
            inOrderTraverse(node.getRightChild());
        }
    }
    // 中序遍历
    private void iterativeInorderTraverse() {
        Deque<BinaryNode> nodeStack = new LinkedList<>();
        BinaryNode<T> currentNode = root;
        while(!nodeStack.isEmpty() || currentNode != null) {
            while (currentNode != null) {
                nodeStack.push(currentNode);
                currentNode = currentNode.getLeftChild();
            }

            if (!nodeStack.isEmpty()) {
                BinaryNode<T> nextNode = nodeStack.pop();
                assert nextNode != null;
                System.out.println(nextNode.getData());
                currentNode = nextNode.getRightChild();
            }
        }
    }
}
二叉树遍历

前序遍历

class Solution {
    public List<Integer> preorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        preorder(root, res);
        return res;
    }

    public void preorder(TreeNode root, List<Integer> res) {
        if (root == null) {
            return;
        }
        res.add(root.val);
        preorder(root.left, res);
        preorder(root.right, res);
    }
}

链接:https://leetcode-cn.com/problems/binary-tree-preorder-traversal/solution/er-cha-shu-de-qian-xu-bian-li-by-leetcode-solution/

中序遍历

class Solution {
    public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        inorder(root, res);
        return res;
    }

    public void inorder(TreeNode root, List<Integer> res) {
        if (root == null) {
            return;
        }
        inorder(root.left, res);
        res.add(root.val);
        inorder(root.right, res);
    }
}

链接:https://leetcode-cn.com/problems/binary-tree-inorder-traversal/solution/er-cha-shu-de-zhong-xu-bian-li-by-leetcode-solutio/

后序遍历

class Solution {
    public List<Integer> postorderTraversal(TreeNode root) {
        List<Integer> res = new ArrayList<Integer>();
        postorder(root, res);
        return res;
    }

    public void postorder(TreeNode root, List<Integer> res) {
        if (root == null) {
            return;
        }
        postorder(root.left, res);
        postorder(root.right, res);
        res.add(root.val);
    }
}

链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/solution/er-cha-shu-de-hou-xu-bian-li-by-leetcode-solution/

层序遍历

class Solution {
    public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> ret = new ArrayList<List<Integer>>();
        if (root == null) {
            return ret;
        }

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            List<Integer> level = new ArrayList<Integer>();
            int currentLevelSize = queue.size();
            for (int i = 1; i <= currentLevelSize; ++i) {
                TreeNode node = queue.poll();
                level.add(node.val);
                if (node.left != null) {
                    queue.offer(node.left);
                }
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            ret.add(level);
        }
        
        return ret;
    }
}

链接:https://leetcode-cn.com/problems/binary-tree-level-order-traversal/solution/er-cha-shu-de-ceng-xu-bian-li-by-leetcode-solution/

红黑树

TreeMap

public class TreeMap<K,V>
    extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
    static final class Entry<K,V> implements Map.Entry<K,V> {
        K key;
        V value;
        Entry<K,V> left;
        Entry<K,V> right;
        Entry<K,V> parent;
        boolean color = BLACK;

        Entry(K key, V value, Entry<K,V> parent) {
            this.key = key;
            this.value = value;
            this.parent = parent;
        }
    }
    
    public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
            compare(key, key); // type (and possibly null) check

            root = new Entry<>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            @SuppressWarnings("unchecked")
                Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }
    
    public V get(Object key) {
        Entry<K,V> p = getEntry(key);
        return (p==null ? null : p.value);
    }
    
    final Entry<K,V> getEntry(Object key) {
        // Offload comparator-based version for sake of performance
        if (comparator != null)
            return getEntryUsingComparator(key);
        if (key == null)
            throw new NullPointerException();
        @SuppressWarnings("unchecked")
            Comparable<? super K> k = (Comparable<? super K>) key;
        Entry<K,V> p = root;
        while (p != null) {
            int cmp = k.compareTo(p.key);
            if (cmp < 0)
                p = p.left;
            else if (cmp > 0)
                p = p.right;
            else
                return p;
        }
        return null;
    }
    
    private void rotateLeft(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> r = p.right;
            p.right = r.left;
            if (r.left != null)
                r.left.parent = p;
            r.parent = p.parent;
            if (p.parent == null)
                root = r;
            else if (p.parent.left == p)
                p.parent.left = r;
            else
                p.parent.right = r;
            r.left = p;
            p.parent = r;
        }
    }

    /** From CLR */
    private void rotateRight(Entry<K,V> p) {
        if (p != null) {
            Entry<K,V> l = p.left;
            p.left = l.right;
            if (l.right != null) l.right.parent = p;
            l.parent = p.parent;
            if (p.parent == null)
                root = l;
            else if (p.parent.right == p)
                p.parent.right = l;
            else p.parent.left = l;
            l.right = p;
            p.parent = l;
        }
    }
}
posted @ 2021-01-18 11:36  曹自标  阅读(121)  评论(0编辑  收藏  举报