借用一张图,直观对比各种排序算法的性能
1.快速排序
要点:每次选择一个**基准元素**pivot,将小于pivot的移到左边,大于pivot的移到右边。
这个动图很赞 这里写链接内容
int mypartition(int* array, int left, int right) {
int pivot = array[left];
int low = left, high = right;
while (low < high) {
while (low<high&&array[high]>=pivot)//注意等于号
--high;
array[low] = array[high];
while (low < high&&array[low] <= pivot)//注意等于号
++low;
array[high] = array[low];
}
array[low] = pivot;
return low;
}
void myQuickSort(int* array, int left, int right) {
if (left < right) {
int pivot = mypartition(array, left, right);
myQuickSort(array, left, pivot - 1);
myQuickSort(array, pivot + 1, right);
}
}
2、冒泡排序
两两比较,把较大的往右移。一共需要n-1。
冒泡是稳定的,两两比较,而且只存在一个方向上的移动。
//升序
void bubbleSort(int* A, int n) {
for (int i = 1; i < n; i++) {
for (int j = 0; j < n - i; j++) {
if (A[j] > A[j + 1])//大的往右移
swap(A[j], A[j + 1]);
}
}
}
3、选择排序
每趟选出待排序元素中最小的一个,与前面的交换。
不稳定:因为位于前面的元素可能会被换到最后面。
//升序
void selectSort(int* A, int n) {
for (int i = 0; i < n - 1; i++) {
int k = i;
for (int j = i + 1; j < n; j++) {
if (A[j] < A[k])//记录最小的元素下标
k = j;
}
swap(A[i], A[k]);
}
}
4、插入排序
假设左边是有序的,右边是无序的。把右边的元素依次插入左边。
插入的规则:往左比较,如果小于左边,则把左边的元素右移腾出位置。
稳定的
void insertSort(int* A, int n) {
int j;
for (int i = 1; i < n; i++) {
int v = A[i];
int j = i - 1;
for (; j >= 0 && v < A[j]; j--)//如果小于,其他元素右移腾出一个位置
A[j + 1] = A[j];
A[j+1] = v;
}
}
5、归并排序
分治法,把数据分成很多小份让它们有序,然后再合并
是稳定的。
void merge(int*A, int left,int mid, int right, int* temp) {
int i = left, j = mid + 1;
int m = mid, n = right;
int k = 0;
while (i <= m&&j <= n) {
if (A[i] <= A[j])//小的先放左边
temp[k++] = A[i++];
else
temp[k++] = A[j++];
}
while (i <= m)
temp[k++] = A[i++];
while (j <= n)
temp[k++] = A[j++];
for (i = 0; i < k; i++)
A[left + i] = temp[i];
}
void mergeSort2(int* A, int left, int right,int* temp) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort2(A, left, mid, temp);
mergeSort2(A, mid + 1, right, temp);
merge(A, left, mid, right, temp);
}
}
参考博文:
视觉直观感受7种常用排序算法
八大排序算法