Skip to content

Sort Algorithm Summary

Xin Wan edited this page Jan 11, 2018 · 4 revisions

Quick Sort

Selection Sort

The solution is: 每次for-loop找到最小值的位置,然后与其实位置进行交换。

  • The first attempt
public void selectionSort(intp[] array) {
	if (array == null || array.length == 0) {
		return;
	}

	int minPos = -1;
	for (int i = 0; i < array.length; i++) {
		for (int j = i; j < array.length; j++) {
			if (i == j) {
				minPos = i;
			} else if (array[minPos] > array[j]) {
				minPos = j;
			}
		}

		swap(array, minPos, i);
	}
}

private void swap(int[] array, int x, int y) {
	int tmp = array[x];
	int array[x] = array[y];
	array[y] = tmp;
}

The bad thing is the following, which is unnecessary:

int minPos = -1;
if (i == j) {
    minPos = i;
} 
  • The second attempt
public void selectionSort(intp[] array) {
	if (array == null || array.length == 0) {
		return;
	}

	for (int i = 0; i < array.length; i++) {

		int minPos = i;
		for (int j = i + 1; j < array.length; j++) {
			if (array[minPos] > array[j]) {
				minPos = j;
			}
		}

		swap(array, minPos, i);
	}
}

private void swap(int[] array, int x, int y) {
	int tmp = array[x];
	int array[x] = array[y];
	array[y] = tmp;
}

Merge Sort

I think mergeSort algorithm should be inplace sort algorithm. Time: O(nlogn) Space: O(n)

public class MergeSortClass {

	private int[] helper;
	public void mergeSort(int[] array) {
		if (array == null || array.length == 0) {
			return;
		}
		helper = new int[array.length];
		mergeSortHelper(array, 0, array.length - 1);
	}

	private void mergeSortHelper(int[] array, int left, int right) {
		if (right <= left) {
			return;
		}

		int mid = (right - left) / 2 + left;
		mergeSortHelper(array, left, mid);
		mergeSortHelper(array, mid + 1, right);

		merge(array, left, mid + 1, right);
	}

	private void merge(int[] array, int left, int mid, int right) {
		for (int i = left; i <= right; i++) {
			helper[i] = array[i];
		}

		int first = left;
		int second = mid;
		int pos = left;

		while (first <= mid && second <= right) {
			if (helper[first] < helper[second]) {
				array[pos++] = helper[first++];
			} else {
				array[pos++] = helper[second++];
			}
		}

		while (first <= mid) {
			array[pos++] = helper[first++];
		}

		while (second <= right) {
			array[pos++] = helper[second++];
		}
	}
}

经典题型

  • Sort A1B2C3D4 -> ABCD1234
  • (Advanced) Sort ABCD1234 -> A1B2C3D4 The idea: ABCD | 1234 AB CD 12 34 AB 21DC 34 AB 12 CD 34 -> AB12 CD34 Sort中存在两次reverse,这道题中不需要merge,merge 就是保持两个排好array的既定顺序
public class MergeSortSample {
	public static void main(String[] args) {
		MergeSortSample sample = new MergeSortSample();

		String input = "ABCD1234";
		System.out.println("Before MergeSort: " + input);
		System.out.println("Result: " + sample.mergeSort(input));
	}

	private String mergeSort(String input) {
		char[] array = new char[input.length()];
		for (int i = 0; i < array.length; i++) {
			array[i] = input.charAt(i);
		}

		mergeSortHelper(array, 0, array.length - 1);

		String result = "";
		for (char c : array) {
			result += c;
		}

		return result;
	}

	private void mergeSortHelper(char[] array, int left, int right) {
		if (left >= right) {
			return;
		}

		int len = right - left + 1;

		int first = left + len / 4;
		int second = left + len * 2 / 4;
		int third = left + len * 3 / 4;

		reverse(array, first, third - 1);
		reverse(array, first, second - 1);
		reverse(array, second, third - 1);

		mergeSortHelper(array, left, second - 1);
		mergeSortHelper(array, second, right);

	}

	private void reverse(char[] array, int left, int right) {
		while (left < right) {
			char tmp = array[left];
			array[left] = array[right];
			array[right] = tmp;
			left++;
			right--;
		}
	}

}
  1. Instead of sorting the number directly, it will sort their index.
  2. mergeSort method 没有什么变化, merge method 变化很大,left side的元素和right side 的元素会相互比较,最终结果存到count[]中。
class Solution {
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> result = new ArrayList<Integer>();
        
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        int[] index = new int[nums.length];
        int[] count = new int[nums.length];
        
        for (int i = 0; i < nums.length; i++) {
            index[i] = i;
        }
        mergeSort(nums, index, count, 0, nums.length - 1);
        
        for (int c : count) {
            result.add(c);
        }
        
        return result;
    }
    
    private void mergeSort(int[] num, int[] index, int[] count, int left, int right) {
        if (left >= right) {
            return;
        }
        
        int mid = (right - left) / 2 + left;
        mergeSort(num, index, count, left, mid);
        mergeSort(num, index, count, mid + 1, right);
        
        merge(num, index, count, left, mid, right);
    }
    
    private void merge(int[] num, int[] index, int[] count, int left, int mid, int right) {
        int[] tmp = new int[right - left + 1];
        
        int leftIdx = left;
        int rightIdx = mid + 1;
        int idx = 0;
        int rightCount = 0;
        while (leftIdx <= mid && rightIdx <= right) {
            if (num[index[leftIdx]] > num[index[rightIdx]]) {
                tmp[idx] = index[rightIdx++];
                rightCount++;
            } else {
                tmp[idx] = index[leftIdx];
                count[index[leftIdx++]] += rightCount;
            }
            idx++;
        }
        
        while (leftIdx <= mid) {
            tmp[idx] = index[leftIdx];
            count[index[leftIdx]] += rightCount;
            idx++;
            leftIdx++;
        }
        
        while (rightIdx <= right) {
            tmp[idx++] = index[rightIdx++];
        }
        
        for (int i = 0; i < right - left + 1; i++) { //Notice it is right - left + 1 rather than right - left.
            index[i + left] = tmp[i];
        }
    }
}

Quick Sort

Bubble Sort

Bucket Sort

Clone this wiki locally