常用排序算法
1.冒泡排序
元素交换
排序最常用的操作就是交换数组中的元素,封装成一个函数,方便后续工作。
/*交换数组元素*/
void swap(int &a,int &b)
{
int temp = a;
a = b;
b = temp;
}
主函数
#include<iostream>
using namespace std;
int main()
{
int arry[] = { 2,4,1,9,4,5,8,7};
int len = (int) sizeof(arry) / sizeof(*arry);
cout << "待排序序列:" ;
for (int i = 0; i < len; i++)
cout << arry[i] << ' ';
cout << endl;
/*调用排序函数*/
/* Sort();
/* */
cout << "排序后序列:";
for (int i = 0; i < len; i++)
cout << arry[i] << ' ';
cout << endl;
return 0;
}
冒泡排序(BubbleSort):相邻元素两两比较,反序(升序或降序)则交换。
/*Bubble Sort*/
void BubbleSort(int arry[], int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (arry[j] > arry[j + 1])
{
swap(arry[j],arry[j+1]);
}
}
}
}
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
算法稳定性:稳定排序算法。
2.选择排序
选择排序(SelectSort):每一次遍历数组,选取最小的元素作为i的关键字。
void SelectSort(int arry[], int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = i + 1; j < len; j++)
{
int temp;
if (arry[i] > arry[j])
{
swap(arry[i], arry[j]);
}
}
}
}
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
算法稳定性:不稳定的排序算法。
3.插入排序
插入排序(InsertSort):将一个元素插入到已经排好的序列中,从而得到一个新的有序的序列。(例:理扑克牌)
void InsertSort(int arry[], int len)
{
for (int i = 1; i < len; i++)
{
for (int j = i - 1; j >= 0 && arry[j + 1] < arry[j]; j--)
{
swap(arry[j], arry[j + 1]);
}
}
}
时间复杂度:
O
(
n
2
)
O(n^2)
O(n2)
空间复杂度:
O
(
1
)
O(1)
O(1)
算法稳定性:稳定的排序算法。
4.希尔排序
希尔排序(ShellSort):把数组元素按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个数组恰被分成一组。
void ShellSort(int arry[], int len)
{
int i, j;
int increment = len;
do
{
increment = increment / 3 + 1;//增量序列
for (i = increment + 1; i <= len; i++)
{
if (arry[i] < arry[i - increment])
{
arry[0] = arry[i];
for (j = i - increment; j > 0 && arry[0] < arry[j]; j -= increment)
arry[j + increment] = arry[j];
arry[j + increment] = arry[0];
}
}
} while (increment > 1);
}
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
空间复杂度:
O
(
1
)
O(1)
O(1)
算法稳定性:不稳定的排序算法。
5.堆排序
堆排序(HeapSort):是利用堆(大顶堆、小顶堆)这种数据结构而设计的一种排序算法,堆排序是一种选择排序。
S1. 将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。
S2. 交换堆顶元素与末尾元素,使末尾元素最大。然后继续调整堆,重复交换。
void HeapAdjust(int arry[],int left,int len)
{
int temp=arry[left];
for (int i = 2 * left; i <= len; i *= 2)
{
if (i < len && arry[i] < arry[i + 1])
++i;
if (temp > arry[i])
break;
arry[left] = arry[i];
left = i;
}
arry[left] = temp;
}
void HeapSort(int arry[], int len)
{
for (int i = len / 2; i > 0; i--) //构建大顶堆
{
HeapAdjust(arry, i, len);
}
for (int i = len; i > 1; i--)
{
swap(arry[i], arry[1]);
HeapAdjust(arry, 1, i-1);
}
}
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
空间复杂度:
O
(
1
)
O(1)
O(1)
算法稳定性:不稳定的排序算法。
6.归并排序
归并排序(MergeSort):采用分治法,将已有序的子序列合并,得到完全有序的序列。
void Merge(int arry[], int L, int mid, int R)
{
int *temp = new int(R - L + 1);
int p1 = L, p2 = mid + 1, i = 0;
while (p1 <= mid && p2 <= R)
{
temp[i++] = arry[p1] > arry[p2] ? arry[p2++] : arry[p1++];
}
while (p1 <= mid)
temp[i++] = arry[p1++];
while (p2 <= R)
temp[i++] = arry[p2++];
for (int i = 0; i < R - L + 1; i++)
{
arry[L + i] = temp[i];
}
delete []temp;
}
void MergeSort(int arry[], int L, int R)
{
if (L< R)
{
int mid = L+(R-L) / 2;
MergeSort(arry, L, mid);
MergeSort(arry, mid + 1, R);
Merge(arry, L, mid, R);
}
}
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
空间复杂度:
O
(
n
)
O(n)
O(n)
算法稳定性:不稳定的排序算法。
7.快速排序
快速排序(QuickSort):先从数列中取出一个数作为基准数,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边,再对左右区间重复第二步,直到各区间只有一个数。 递归实现
void Quick_sort(int arry[], int l, int r)
{
if (l < r)
{
int i = l, j = r, x = arry[l];
while (i < j)
{
while (i < j && arry[j] >= x)
j--;
if (i < j)
arry[i++] = arry[j];
while (i < j && arry[i] < x)
i++;
if (i < j)
arry[j--] = arry[i];
}
arry[i] = x;
Quick_sort(arry, l, i - 1); // 递归调用
Quick_sort(arry, i + 1, r);
}
}
时间复杂度:
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
空间复杂度:
O
(
n
)
O(n)
O(n)
算法稳定性:不稳定的排序算法。
推荐书籍《大话数据结构》—程杰
大话数据结构
提取码:fwsr