常用排序算法小结
声明
文章均为本人技术笔记,转载请注明出处:
[1] https://segmentfault.com/u/yzwall
[2] blog.csdn.net/j_dark/
排序说明
排序算法默认升序排序
测试题目lintcode Sort Integers和lintcode Sort IntegersⅡ(要求$O(ntimeslog n)$时间复杂度)
代码简洁起见,提供交换方法
swap
:
private void swap(int[] A, int index1, int index2) {
if (index1 == index2) {
return;
}
int temp = A[index1];
A[index1] = A[index2];
A[index2] = temp;
}
1 选择排序
“选择”:选择排序实现方式最简单,每次排序将$A[i]~A[A.length - 1]$中的最小值$A[minIndex]$与$A[i]$交换位置,选择(最小值)与输入无关,效率最慢;
/**
* 选择排序(升序)
* 时间复杂度O(n^2),空间复杂度O(1)
* @author yzwall
*/
class Solution {
public void sortIntegers(int[] A) {
for (int i = 0; i < A.length; i++) {
int minIndex = i;
for (int j = i + 1; j < A.length; j++) {
minIndex = A[minIndex] > A[j] ? j : minIndex;
}
swap(A, i, minIndex);
}
}
}
2 冒泡排序
“冒泡”:每次冒泡将最大值(升序)移动到当前排序数组区间的最后一位,即向右冒泡,因此$A[j - 1]$始终维护冒泡区间中的极大值;
/**
* 冒泡排序(升序)
* 时间复杂度O(n^2),空间复杂度O(1)
* @author yzwall
*/
class Solution {
public void sortIntegers(int[] A) {
// i负责维护冒泡区间右边界为A[i - 1]
for (int i = A.length; i > 0; i--) {
// 冒泡区间为A[0]~A[i - 1],最大值冒泡到末位置(升序)
for (int j = 1; j < i; j++) {
if (A[j - 1] > A[j]) {
swap(A, j, j - 1);
}
}
// 一遍冒泡后,A[i - 1]为数组A[0] ~ A[i - 1]中最大值
}
}
}
3 直接插入排序
“插入”:每次将待排序元素插入到左侧的有序(升序)列中,即向左插入, $A[j]$始终维护插入元素在有序列中的位置;
/**
* 直接插入排序(升序)
* 时间复杂度O(n^2),空间复杂度O(1)
* @author yzwall
*/
class Solution {
public void sortIntegers(int[] A) {
// 将A[i]~A[A.length - 1]每个数插入到左侧的有序列中
for (int i = 1; i < A.length; i++) {
for (int j = i; j > 0; j--) {
if (A[j] < A[j - 1]) {
swap(A, j, j - 1);
}
}
}
}
}
4 希尔排序
待补充;
4 归并排序
/**
* http://www.lintcode.com/en/problem/sort-integers-ii/
* 归并排序一个整型数组(升序)
* @author yzwall
*/
class Solution {
public void sortIntegers2(int[] A) {
if (A == null || A.length == 0) {
return;
}
mergeSort(A, 0, A.length - 1);
}
public void mergeSort(int[] A, int start, int end) {
if (start >= end) {
return;
}
int mid = start + (end - start) / 2;
mergeSort(A, start, mid);
mergeSort(A, mid + 1, end);
merge(A, start, end);
}
private void merge(int[] A, int start, int end) {
int mid = start + (end - start) / 2;
int i = start, j = mid + 1, index = 0;
int[] temp = new int[end - start + 1];
while (i <= mid && j <= end) {
if (A[i] < A[j]) {
temp[index++] = A[i++];
} else {
temp[index++] = A[j++];
}
}
while (i <= mid) {
temp[index++] = A[i++];
}
while (j <= end) {
temp[index++] = A[j++];
}
for (int k = 0; k < index; k++) {
A[start + k] = temp[k];
}
}
}
5 快速排序
/**
* http://www.lintcode.com/en/problem/sort-integers-ii/
* 快速排序一个整型数组(升序)
* @author yzwall
*/
class Solution {
public void sortIntegers2(int[] A) {
if (A == null || A.length == 0) {
return;
}
quickSort(A, 0, A.length - 1);
}
public void quickSort(int[] A, int start, int end) {
if (start >= end) {
return;
}
int pivot = A[start + (end - start) / 2];
int left = start, right = end;
while (left <= right) {
while (left <= right && A[left] < pivot) {
left++;
}
while (left <= right && A[right] > pivot) {
right--;
}
if (left <= right) {
int temp = A[left];
A[left] = A[right];
A[right] = temp;
left++;
right--;
}
}
quickSort(A, start, right);
quickSort(A, left, end);
}
}
6 堆排序
6 桶排序
待补充;
7 计数排序
待补充;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。