常用排序算法詳解(快排,歸併,堆排序,插入,選擇)

QuickSort

https://github.com/hustcc/JS-Sorting-Algorithm/blob/master/6.quickSort.md
https://www.cnblogs.com/guoyaohua/p/8600214.html

package algs;

import java.lang.Math;

public class QuickSort {
  public static int[] sort (int[] a) {
    return sort(a, 0, a.length-1);
  }
  // Divide and Conquer
  public static int[] sort (int[] a, int lo, int hi) {
    if (lo < hi) {
      int pivot = partition2(a, lo, hi);
      sort(a, lo, pivot-1);
      sort(a, pivot+1, hi);
    }
    return a;
  }
  // double pointer to one direction
  // quicker one tranverse, slower one point to < pivot value
  // swap of quicker and slower
  public static int partition(int[] a, int lo, int hi) {
    int pivot = (int)(lo + Math.random()*(hi-lo)); //Or Random rand = new Java.util.Random(); rand.nextInt(hi-lo+1)
    swap(a, lo, pivot);
    int v = a[lo];
    int i = lo+1;
    for (int j = i; j <= hi; j++) {
      if (a[j] < v) {
        // non-stable here!
        if (j != i) {
          swap(a, i, j);
        }
        // // or use stable statements
        // int k = j;
        // while (k != i) {
        //    swap(a, k-1, k);
        // }
        i++;
      }
    }
    swap(a, lo, i-1);
    return i-1;
  }
  // double pointer have opposite direction
  // left one <= pivot value to right, right one >= pivot value to left
  // swap at both stopped point
  public static int partition2(int[] a, int lo, int hi) {
    int pivot = (int)(lo + Math.random()*(hi-lo));
    swap(a, lo, pivot);
    int v = a[lo];
    int i = lo+1, j = hi;
    while(true) {
      while (i < hi &&  a[i] <= v ) {
        i++;
      }
      while (j > lo &&  a[j] >= v ) {
        j--;
      }
      if (i >= j) {
        swap(a, lo, j);
        return j;
      }
      swap(a, i, j);
    }
  }
  // similar as partition1
  // Note, a[i] <= pivot value
  public static int partition3(int[] array, int start, int end) {
    int pivot = (int) (start + Math.random() * (end - start));
    int smallIndex = start - 1;
    swap(array, pivot, end);
    for (int i = start; i <= end; i++)
      if (array[i] <= array[end]) {
        smallIndex++;
        if (i > smallIndex)
          swap(array, i, smallIndex);
      }
    return smallIndex;
  }
  public static void swap(int[]a, int i, int j) {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
  }
  public static boolean isSorted(int[] a) {
    boolean isSorted = true;
    for (int i = 0; i < a.length - 1; i++) {
      if (a[i] > a[i+1]) {
        isSorted = false;
      }
    }
    return isSorted;
  }
  public static void main (String[] args){
    int N = 10;
    int [] a = new int[10];
    for (int i = 0; i < N; i++) {
      a[i] = (int)(Math.random()*N);
    }
    for (int i : a) {
      System.out.print(i+",");
    }
    int[] r = sort(a);
    System.out.println("\nisSorted? " + isSorted(r));
    for (int i : r) {
      System.out.print(i+",");
    }
  }
}

MergeSort

package algs;

import java.util.Arrays;

public class MergeSort {
  public static int[] sort(int[] a) {
    if (a.length < 2) return a;
    int mid = a.length / 2;
    int[] left = Arrays.copyOfRange(a, 0, mid);
    int[] right = Arrays.copyOfRange(a, mid, a.length);
    return merge(sort(left), sort(right));
  }

  public static int[] merge (int[] left, int[] right) {
    int[] result = new int[left.length + right.length];
    for (int k = 0, i = 0, j = 0; k < result.length; k++) {
      if (i >= left.length)
        result[k] = right[j++];
      else if (j >= right.length)
        result[k] = left[i++];
      else if (left[i] > right[j])
        result[k] = right[j++];
      else
        result[k] = left[i++];
    }
    return result;
  }
  public static boolean isSorted(int[] a) {
    boolean isSorted = true;
    for (int i = 0; i < a.length - 1; i++) {
      if (a[i] > a[i+1]) {
        isSorted = false;
      }
    }
    return isSorted;
  }
  public static void main (String[] args){
    int N = 10;
    int [] a = new int[10];
    for (int i = 0; i < N; i++) {
      a[i] = (int)(Math.random()*N);
    }
    int[] r = sort(a);
    System.out.println("isSorted? " + isSorted(r));
    for (int i : r) {
      System.out.println(i);
    }
  }
}


SelectionSort

package algs;

public class SelectionSort {
  public static int[] sort(int[] a) {
    for (int i = 0; i < a.length; i++) {
      int minIndex = i;
      for (int j = i+1; j < a.length; j++) {
        if (a[j] < a[minIndex]) {
          minIndex = j;
        }
      }
      if (i != minIndex) {
        swap(a, i, minIndex);
      }
    }
    return a;
  }
  public static void swap(int[]a, int i, int j) {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
  }
  public static boolean isSorted(int[] a) {
    boolean isSorted = true;
    for (int i = 0; i < a.length - 1; i++) {
      if (a[i] > a[i+1]) {
        isSorted = false;
      }
    }
    return isSorted;
  }
  public static void main (String[] args){
    int N = 10;
    int [] a = new int[10];
    for (int i = 0; i < N; i++) {
      a[i] = (int)(Math.random()*N);
    }
    int[] r = sort(a);
    System.out.println("isSorted? " + isSorted(r));
    for (int i : r) {
      System.out.println(i);
    }
  }
}

InsertionSort

package algs;


public class InsertionSort {
  public static int[] sort(int[] a) {
  	if (a.length < 2) {
  		return a;
  	}
    for (int i = 1; i < a.length; i++) {
      int v = a[i];
      int j = i-1;
      while(j >=0 && a[j]>a[j+1]){
        swap(a, j, j+1);
        j--;
      }
	// Or:
	//      while(j >= 0 && a[j] >v) {
	//        a[j+1] = a[j];
	//        j--;
	//      }
	//      a[j+1] = v;

    }
    
    return a;
  }
  // Or
  public static int[] sort2(int[] nums) {
      if (nums == null || nums.length < 2) return nums;
      // 從0開始比較自然
      for (int i = 0; i < nums.length-1; i++) {
          int j = i;
          while (j >= 0 && nums[j] > nums[j+1]) {
              swap(nums, j, j+1);
              j--;
          }
          // Or
          // int v = nums[i+1];
          // while (j >= 0 && nums[j] > v) {
          // 	nums[j+1] = nums[j];
          //	j--;
          // }
          // nums[j+1] = v;
      }
      return nums;
  }
  public static void swap(int[]a, int i, int j) {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
  }
  public static boolean isSorted(int[] a) {
    boolean isSorted = true;
    for (int i = 0; i < a.length - 1; i++) {
      if (a[i] > a[i+1]) {
        isSorted = false;
      }
    }
    return isSorted;
  }
  public static void main (String[] args){
    int N = 10;
    int [] a = new int[10];
    for (int i = 0; i < N; i++) {
      a[i] = (int)(Math.random()*N);
    }
    for (int i : a) {
      System.out.print(i+",");
    }
    int[] r = sort(a);
    System.out.println("\nisSorted? " + isSorted(r));
    for (int i : r) {
      System.out.print(i+",");
    }
  }
}

HeapSort 大頂堆,排序結果從小到大

package algs;

import static algs.SelectionSort.isSorted;
import static algs.SelectionSort.swap;

public class HeapSort {
  private HeapSort(){}
  public static int[] sort(int[] a) {
    int aLen = a.length;
    // constructing buildMaxHeap(a, aLen);
   	for (int i = aLen / 2; i >= 0; i--) {
      adjustHeap(a, i, aLen);
    }
    // swap tail and top, decrease heap size, then adjust heap from top
    for (int i = aLen-1; i >=0; i--) {
      swap(a,0, i);
      adjustHeap(a,0,aLen--);
    }
    return a;
  }

  // recursive adjust heap
  // 所謂調整堆,單位操作即是:比較某節點的左右子節點,找出最大的;如果最大的不是根節點,則交換最大節點爲根節點,如此遞歸。
  public static void adjustHeap(int[] a, int i, int aLen){
    int maxIndex = i, left = 2*i+1, right = 2*i+2;
    if (left < aLen && a[left] > a[maxIndex] ) {
      maxIndex = left;
    }
    if (right < aLen && a[right] > a[maxIndex]) {
      maxIndex = right;
    }
    if (maxIndex != i) {
      swap(a, i, maxIndex);
      adjustHeap(a, maxIndex, aLen);
    }
  }
  public static void main (String[] args){
    int N = 10;
    int [] a = new int[10];
    for (int i = 0; i < N; i++) {
      a[i] = (int)(Math.random()*N);
    }
    for (int i : a) {
      System.out.print(i+",");
    }
    int[] r = sort(a);
    System.out.println("\nisSorted? " + isSorted(r));
    for (int i : r) {
      System.out.print(i+",");
    }
  }
}

KMP

package algs;

public class KMP {
  public static int index(String ts, String ps) {
    char[] t = ts.toCharArray();
    char[] p = ps.toCharArray();
    int i = 0, j = -1;
    int[] next = getNext(p);
    while (i < t.length && j < p.length){
      if (j == -1 || t[i] == p[j]) {
        i++;
        j++;
      } else {
        j = next[j];
      }
    }
    if (j == p.length){
      return i-j;
    } else {
      return -1;
    }

  }

// 前綴後綴匹配字串最大長度數組 -》右移+首位填-1
  public static int[] getNext(char[] p) {
    int j = 0, k = -1;
    int[] next = new int[p.length];
    next[0] = -1;
    while (j < p.length-1) {
      if (k == -1 || p[j] == p[k]) {
        if (p[++j] == p[++k]) {
          next[j] = next[k];
        } else {
          next[j] = k;
        }
      } else {
        k = next[k];
      }
    }
    return next;
  }

  public static void main(String[] args){
    String ps = "ababa";
    String ts = "abcdababaxy";
    int i = index(ts, ps);
    System.out.println(i);

  }

}

TreeGenerator

package algs;

import java.util.*;

import java.lang.Math;
import java.util.Arrays;

public class TreeGenerator {
  public static void main(String[] args) {
    Random rand = new Random();
    int[] res = getRandomArray(rand, 4);
    for (int r : res) {
      System.out.println(r);
    }
  }

  private static class Node {
    int item;
    Node left;
    Node right;
    Node(int item) {
      this.item = item;
    }
  }

  public static Node generateTree(int size, int range, boolean fullBinaryTree) {
    if (size <= 0) {
      return null;
    }
    Random rand = new Random();
    // generate random node list
    List<Node> nodeList = new ArrayList<>();
    for (int i = 0; i < size; i++) {
      int randomItem = rand.nextInt(range);
      Node node = new Node(randomItem);
      nodeList.add(node);
    }

    // link nodes in node list
    int rowFirst = 0;
    int rowTail = 0;
    for (int i = 0; i < size; i++) {
      int[] randomArr = getRandomArray(rand, rowTail-rowFirst+1);
      for (int j = 0; j < randomArr.length; j++) {
        int index = randomArr[j];

      }

    }
    return nodeList.get(0);
  }
  private static int[] getRandomArray(Random rand, int range) {
    int[] tmp = new int[range];
    int num = rand.nextInt(range)+1;
    for (int i = 0; i < num; i++) {
      tmp[rand.nextInt(range)] = 1;
    }
    return tmp;
  }
}

climbStairs

package algs;

public class ClimbStairs {
  public static int calculateCount(int ladder, int maxJump) {
    int solution = 0;
    if (ladder == 0) {
      return 1;
    }
    if (ladder >= maxJump) {
      // 剩下的樓梯大於最大可跳躍數
      for (int i = 1; i <= maxJump; i++) {
        solution += calculateCount(ladder - i, maxJump);
      }
    } else {
      // 剩下的樓梯不足最大可跳躍數
      solution = calculateCount(ladder, ladder);
    }
    return solution;
  }
  // dynamic programming
  // 動態規劃的要點:
  // 1.最優子結構 2.邊界 3.狀態轉移方程
  // steps: n, maxJmp: m
  // f[n] = f[n-1] +...+ f[n-m] (n-m>=0)
  // f[0] = 0; f[1] = f[0]; f[2] = f[1]+f[0]; ...
  public static int dp(int ladder, int maxJump) {
    if (ladder <= maxJump) {
      return initialState(ladder);
    }
    int solution = 0;
    int[] dpTable = new int[maxJump];
    for (int i = 0; i < maxJump; i++) {
      dpTable[i] = dp(i, maxJump);
    }
    for (int i = 0; i < ladder; i++) {
      for (int j = 0; j < maxJump-1; j++) {
        solution += dpTable[j];
        dpTable[j] = dpTable[j+1];
      }
      dpTable[maxJump-1] = solution;
    }
    return solution;
  }
  private static int initialState(int ladder) {
    if (ladder == 0 || ladder == 1) {
      return 1;
    }
    return initialState(ladder-1) + initialState(ladder-2);
  }

  public static void main(String[] args) {
    int ladder = 7;
    int maxJump = 2;
    int i = calculateCount(ladder, maxJump);
    System.out.println(i);
    int res = dp(ladder, maxJump);
    System.out.println(res);
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章