快速排序
快速排序wiki
算法:
快速排序使用分治法策略来把一个序列分为较小和较大的2个子序列,然后递归地排序两个子序列。
步骤为:
1. 挑选基准值:从数列中挑出一个元素,称为“基准”(pivot),
2. 分割:重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(与基准值相等的数可以到任何一边)。在这个分割结束之后,对基准值的排序就已经完成,
3. 递归排序子序列:递归地将小于基准值元素的子序列和大于基准值元素的子序列排序。
递归到最底部的判断条件是数列的大小是零或一,此时该数列显然已经有序。
算法实现:
public class QuickSort {
public static void main(String[] args) {
int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
QuickSort quickSort = new QuickSort();
quickSort.quickSort(waitSort, 0, waitSort.length - 1);
System.out.println(Arrays.toString(waitSort));
}
private void quickSort(int[] nums, int start, int end) {
if (start < end) {
int partition = quickPartition(nums, start, end);
quickSort(nums, start, partition - 1);
quickSort(nums, partition + 1, end);
}
}
private int quickPartition(int[] nums, int start, int end) {
int pivot = nums[start];
int left = start, right = end;
while (left < right) {
while (left < right && nums[left] <= pivot) left++;
while (left < right && pivot <= nums[right]) right--;
if (left < right) {
swap(nums, left, right);
}
}
return left;
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
归并排序
归并排序wiki
算法:
归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。归并排序算法依赖归并操作。
递归法(Top-down)
1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
4. 重复步骤3直到某一指针到达序列尾
5. 将另一序列剩下的所有元素直接复制到合并序列尾
迭代法(Bottom-up)
原理如下(假设序列共有n个元素):
1. 将序列每相邻两个数字进行归并操作,形成ceil(n/2)个序列,排序后每个序列包含两/一个元素
2. 若此时序列数不是1个则将上述序列再次归并,形成ceil(n/4)个序列,每个序列包含四/三个元素
3. 重复步骤2,直到所有元素排序完毕,即序列数为1
算法实现:
public class MergeSort {
public static void main(String[] args) {
int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
MergeSort mergeSort = new MergeSort();
mergeSort.mergeSort(waitSort, 0, waitSort.length - 1);
System.out.println("MergeSort");
System.out.println(Arrays.toString(waitSort));
}
private void mergeSort(int[] nums, int start, int end) {
if (start >= end) return;
int mid = start + (end - start) / 2;
mergeSort(nums, start, mid);
mergeSort(nums, mid + 1, end);
merge(nums, start, mid, end);
}
private void merge(int[] nums, int start, int mid, int end) {
int[] temp = new int[end - start + 1];
int p1 = start, p2 = mid + 1;
int p = 0;
while (p1 <= mid && p2 <= end) {
if (nums[p1] < nums[p2]) temp[p++] = nums[p1++];
if (nums[p1] >= nums[p2]) temp[p++] = nums[p2++];
}
while (p1 <= mid) temp[p++] = nums[p1++];
while (p2 <= end) temp[p++] = nums[p2++];
for (int i = 0; i < temp.length; ++i) {
nums[start + i] = temp[i];
}
}
}
堆排序
堆排序wiki
算法实现:
public class HeapSort {
public static void main(String[] args) {
int[] waitSort = { 100, 50, 30, 20, 40, 70, 80 };
int size = waitSort.length;
HeapSort heapSort = new HeapSort();
for (int i = 0; i < size; ++i) heapSort.heapInsert(waitSort, i);
swap(waitSort, 0, --size);
while (0 < size) {
heapSort.heapify(waitSort, 0, size);
swap(waitSort, 0, --size);
}
System.out.println("HeapSort");
System.out.println(Arrays.toString(waitSort));
}
private void heapInsert(int[] nums, int index) {
while (nums[(index - 1) / 2] < nums[index]) {
swap(nums, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
private void heapify(int[] nums, int index, int size) {
int left = 2 * index + 1;
while (left < size) {
int largest = (left + 1 < size && nums[left] < nums[left + 1]) ? left + 1 : left;
largest = (nums[largest] < nums[index]) ? index : largest;
if (largest == index) break;
swap(nums, index, largest);
index = largest;
left = 2 * index + 1;
}
}
public static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}