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);
}
}