1、直接插入排序
以下代码均为c语言
时间复杂度
最好情况o(n)
最差情况o(n^2)
void InsertSort(int* a, int n)
{
for (int i = 0; i < n - 1; i++) {
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp) {
a[end + 1] = a[end];
end--;
}
else {
break;
}
}
a[end + 1] = tmp;
}
}
2、希尔排序
时间复杂度o(n^1.3)
void ShellSort(int* a, int n) {
int gap = n;
while (gap > 1)
{
//推荐写法;除3
gap = gap / 3 + 1;
//gap=gap/2
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp) {
a[end + tmp] = a[end];
end -= gap;
}
else {
break;
}
}
a[end + gap] = tmp;
}
}
3、直接选择排序
时间复杂度o(n^2)
3.1选择排序
//选择排序
void SelectSort(int* a,int n){
int begin = 0, end = n - 1;
while (begin < end)
{
int mini = begin, maxi = begin;
for (int i = begin; i <= end; i++)
{
if (a[i] > a[maxi]) {
maxi - i;
}
if (a[i] < a[mini]) {
mini = i;
}
}
if (begin = maxi) {
maxi = mini;
}
Swap(&a[mini], &a[begin]);
Swap(&a[maxi], &a[end]);
++begin;
--end;
}
3.2堆排序
时间复杂度o(nlogn)
//向下调整
void adjustDown(int* a, int n, int parent) {
int child = parent * 2 + 1;
while (child < n)
{
//左右子节点进行比较,找到子节点中较大的那个
if (chid + 1 < n && a[child] < a[child + 1]) {
child++;
}
//和父节点进行比较大于就交换
if (a[child] > a[parent]) {
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else {
break;
}
}
}
//2、堆排序
void HeapSort(int* a, int n) {
//1、建堆
//parent=(child-1)/2
for (int i = (n - 1 - 1) / 2; i >= 0 / i--)
{
adjustown(a, n, i);
}
//2、堆排序
int end = n - 1;
while (end > 0)
{
Swap(&a[0], &a[end]);
end--;
adjustDown(a, end, 0);
}
}
4、交换排序
冒泡排序就像烧水一样先将较大的数冒出来
4.1冒泡排序
//1、冒泡排序、
void BubbleSort(int* a, int n) {
int exchange = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - i - 1; j++)
{
if (a[j] > a[j + 1]) {
exchange = 1;
Swap(&a[j], &a[j + 1]);
}
}
if (exchange == 0) {
break;
}
}
}
4.2快速排序
//第一种解法:hoare版本
int _QuickSort(int* a, int left, int right) {
int key = left;
while (left < right) {
// 从右往左遍历,找比基准值要小的
while (left < right && a[right] >= a[key])
--right;
// 从左往右遍历,找比基准值要大的
while (left < right && a[left] <= a[key])
++left;
Swap(&a[left], &a[right]);
}
Swap(&a[left], &a[key]);
return left;
}
// 2. 快速排序
void QuickSort(int* a, int left, int right) {
if (left >= right) {
return;
}
int meet = _QuickSort(a, left, right);
QuickSort(a, left, meet - 1);
QuickSort(a, meet + 1, right);
}
//第二种解法:挖坑法
// 2. 挖坑法
int _QuickSort(int* a, int left, int right) {
int hole = left;
int key = a[hole];
while (left < right) {
while (left < right && a[right] >= key) {
--right;
}
a[hole] = a[right];
hole = right;
while (left < right && a[left] <= key) {
++left;
}
a[hole] = a[left];
hole = left;
}
a[hole] = key;
return hole;
}
5、归并排序
基本思想:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用,将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序,若将两个有序表合并成一个有序表,称为二路归并。
void _MergeSort(int* a, int left, int right, int* tmp) {
if (left >= right) {
return;
}
int mid = (right + left) / 2;
// [left, mid] [mid+1, right]
_MergeSort(a, left, mid, tmp);
_MergeSort(a, mid + 1, right, tmp);
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = begin1;
// 合并两个有序数组为一个数组
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] < a[begin2]) {
tmp[index++] = a[begin1++];
} else {
tmp[index++] = a[begin2++];
}
}
while (begin1 <= end1) {
tmp[index++] = a[begin1++];
}
while (begin2 <= end2) {
tmp[index++] = a[begin2++];
}
for (int i = left; i <= right; i++) {
a[i] = tmp[i];
}
}
void MergeSort(int* a, int n) {
int* tmp = (int*)malloc(sizeof(int) * n);
_MergeSort(a, 0, n-1, tmp);
free(tmp);
}