前言
以下代码环境为vs2022
插入排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
// 插入排序
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;
}
}
int main()
{
int a[10] = { 0 };
int i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
InsertSort(a, 10);
for(i=0;i<10;i++)
{
printf("%d ", a[i]);
}
return 0;
}
希尔排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
// 希尔排序
void ShellSort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;
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 + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
int main()
{
int a[10] = { 0 };
int i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
ShellSort(a, sizeof(a) / sizeof(int));
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
}
选择排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
// 选择排序
void swap(int* x1,int* x2)
{
int x = *x1;
*x1 = *x2;
*x2 = x;
}
void SelectSort(int* a, int n)
{
int begin = 0, end = n - 1;
while (begin < end)
{
int max = begin, min = begin;
for (int i = begin + 1; i <= end; i++)
{
if (a[i] < a[min])
{
min = i;
}
if (a[i] > a[max])
{
max = i;
}
}
swap(&a[min], &a[begin]);
if (max == begin)
{
max = min;
}
swap(&a[max], &a[end]);
begin++;
end--;
}
}
int main()
{
int a[10] = { 0 };
int i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
SelectSort(a, 10);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
堆排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
// 对数组进行堆排序
typedef int HPDataType;
void swap(HPDataType* x1, HPDataType* x2)
{
HPDataType x = *x1;
*x1 = *x2;
*x2 = x;
}
void adjustdown(HPDataType* a, int n, int root)
{
int parent = root;
int child = parent * 2 + 1;
while (child < n)
{
// 选左右孩纸中大的一个
if (child + 1 < n
&& a[child + 1] > a[child])
{
++child;
}
//如果孩子大于父亲,进行调整交换
if (a[child] > a[parent])
{
swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int* a, int n)
{
int i = 0;
//升序 建大堆
for (i = (n - 1 - 1) / 2; i >= 0; i--)
{
adjustdown(a, n, i);//建立的大堆的数组并不是升序
}
int end = n - 1;
while (end > 0)
{
swap(&a[end], &a[0]);
adjustdown(a, end, 0);
end--;
}
}
int main()
{
int a[10] = { 0 };
int i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
ShellSort(a, sizeof(a)/sizeof(int));
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
HeapSort(a, sizeof(a) / sizeof(int));
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
冒泡排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
// 冒泡排序
void swap(int* x1, int* x2)
{
int x = *x1;
*x1 = *x2;
*x2 = x;
}
void BubbleSort(int* a, int n)
{
int i = 0, j = 0;
for (i = 0; i < n; i++)
{
int exchange = 0;
for (j = 1; j < n - i; j++)
{
if (a[j-1] > a[j])
{
swap(&a[j], &a[j - 1]);
exchange = 1;
}
}
if (exchange == 0)
{
break;//一趟冒泡排序中没有发生交换,表示已经有序,退出循环
}
}
}
int main()
{
int a[10] = { 0 };
int i = 10;
while (i--)
{
scanf("%d", &a[i]);
}
BubbleSort(a, 10);
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
快速排序
递归实现
1)hoare快速排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
void swap(int* m, int* n)
{
int tm = *m;
*m = *n;
*n = tm;
}
void quicksort(int* a, int begin, int end)
{
if (begin >= end)
return;
int left = begin, right = end;
int key = left;
while (left < right)
{
while (a[right] >= a[key] && right > left)//当左边第一个为key时,右边先走,这样可以确保与key交换位置的都是比key小的数字,从右向左找比key小的数
{
right--;
}
while (a[left] <= a[key] && right > left)//从左向右找比key大的数
{
left++;
}
swap(&a[left], &a[right]);
}
swap(&a[key], &a[left]);
key = left;
quicksort(a, begin, key - 1);
quicksort(a, key + 1, end);
}
int main()
{
int a[10] = { 12,5,67,23,54,4,12,3,2,90 };
int left1 = 0, right1 = 9;
quicksort(a, left1, right1);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
2)挖坑法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
// 三数取中
// begin mid end
int GetMidIndex(int* a, int begin, int end)
{
int mid = (begin + end) / 2;
if (a[begin] < a[mid])
{
if (a[mid] < a[end])
{
return mid;
}
else if (a[begin] > a[end])
{
return begin;
}
else
{
return end;
}
}
else // a[begin] > a[mid]
{
if (a[mid] > a[end])
{
return mid;
}
else if (a[begin] < a[end])
{
return begin;
}
else
{
return end;
}
}
}
void swap(int* m, int* n)
{
int tm = *m;
*m = *n;
*n = tm;
}
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 (tmp < a[end])
{
a[end + 1] = a[end];
--end;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
int holesort(int* a, int begin, int end)
{
int mid = GetMidIndex(a, begin, end);
swap(&a[begin], &a[mid]);
int left = begin, right = end;
int key = a[left];
int hole = left;
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;
}
void QuickSort(int* a, int begin, int end)
{
if (begin >= end)
{
return;
}
if ((end - begin + 1) < 15)
{
// 小区间用直接插入替代,减少递归调用次数
InsertSort(a + begin, end - begin + 1);
}
else
{
int keyi = holesort(a, begin, end);
// [begin, keyi-1] keyi [keyi+1, end]
QuickSort(a, begin, keyi - 1);
QuickSort(a, keyi + 1, end);
}
}
int main()
{
int a[10] = { 12,5,67,23,54,4,12,3,2,90 };
int left1 = 0, right1 = 9;
QuickSort(a, left1, right1);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
3)前后指针法
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
// 三数取中
// begin mid end
int GetMidIndex(int* a, int begin, int end)
{
int mid = (begin + end) / 2;
if (a[begin] < a[mid])
{
if (a[mid] < a[end])
{
return mid;
}
else if (a[begin] > a[end])
{
return begin;
}
else
{
return end;
}
}
else // a[begin] > a[mid]
{
if (a[mid] > a[end])
{
return mid;
}
else if (a[begin] < a[end])
{
return begin;
}
else
{
return end;
}
}
}
void swap(int* m, int* n)
{
int tm = *m;
*m = *n;
*n = tm;
}
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 (tmp < a[end])
{
a[end + 1] = a[end];
--end;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
int pointsort(int* a, int begin, int end)
{
int mid = GetMidIndex(a, begin, end);
swap(&a[begin], &a[mid]);
int keyi = begin;
int prev = begin, cur = begin + 1;
while (cur <= end)
{
// 找到比key小的值时,跟++prev位置交换,小的往前翻,大的往后翻
if (a[cur] < a[keyi] && ++prev != cur)
swap(&a[prev], &a[cur]);
++cur;
}
swap(&a[prev], &a[keyi]);
keyi = prev;
return keyi;
}
void QuickSort(int* a, int begin, int end)
{
if (begin >= end)
{
return;
}
if ((end - begin + 1) < 15)
{
// 小区间用直接插入替代,减少递归调用次数
InsertSort(a + begin, end - begin + 1);
}
else
{
int keyi = pointsort(a, begin, end);
// [begin, keyi-1] keyi [keyi+1, end]
QuickSort(a, begin, keyi - 1);
QuickSort(a, keyi + 1, end);
}
}
int main()
{
int a[10] = { 12,5,67,23,54,4,12,3,2,90 };
int left1 = 0, right1 = 9;
QuickSort(a, left1, right1);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}
非递归实现
非递归需要以栈为工具,栈用c语言编写分为stack.h 和stack.c两个文件
//这部分代码为stack.h
#pragma once
#include <stdbool.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int STDatatype;
typedef struct Stack
{
STDatatype* a;
int capacity;
int top; // 初始为0,表示栈顶位置下一个位置下标
}ST;
void StackInit(ST* ps);
void StackDestroy(ST* ps);
void StackPush(ST* ps, STDatatype x);
void StackPop(ST* ps);
STDatatype StackTop(ST* ps);
bool StackEmpty(ST* ps);
int StackSize(ST* ps);
#include "Stack.h"//这部分代码为stack.c
void StackInit(ST* ps)
{
assert(ps);
//ps->a = NULL;
//ps->top = 0;
//ps->capacity = 0;
ps->a = (STDatatype*)malloc(sizeof(STDatatype)*4);
if (ps->a == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->top = 0;
ps->capacity = 4;
}
void StackDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = ps->capacity = 0;
}
void StackPush(ST* ps, STDatatype x)
{
assert(ps);
//
if (ps->top == ps->capacity)
{
STDatatype* tmp = (STDatatype*)realloc(ps->a, ps->capacity * 2 * sizeof(STDatatype));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
// 20:20
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
STDatatype StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
bool StackEmpty(ST* ps)
{
assert(ps);
/*if (ps->top == 0)
{
return true;
}
else
{
return false;
}*/
return ps->top == 0;
}
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
//非递归实现快排的函数
int PartSort3(int* a, int begin, int end)
{
//printf("%d,%d\n", begin, end);
int mid = GetMidIndex(a, begin, end);
Swap(&a[begin], &a[mid]);
int keyi = begin;
int prev = begin, cur = begin + 1;
while (cur <= end)
{
// 找到比key小的值时,跟++prev位置交换,小的往前翻,大的往后翻
if (a[cur] < a[keyi] && ++prev != cur)
Swap(&a[prev], &a[cur]);
++cur;
}
Swap(&a[prev], &a[keyi]);
keyi = prev;
return keyi;
}
void QuickSortNonR(int* a, int begin, int end)
{
ST st;
StackInit(&st);
StackPush(&st, begin);
StackPush(&st, end);
while (!StackEmpty(&st))
{
int right = StackTop(&st);
StackPop(&st);
int left = StackTop(&st);
StackPop(&st);
int keyi = PartSort3(a, left, right);
// [left, keyi-1] keyi [keyi+1, right]
if (keyi+1 < right)
{
StackPush(&st, keyi + 1);
StackPush(&st, right);
}
if (left < keyi-1)
{
StackPush(&st, left);
StackPush(&st, keyi - 1);
}
}
StackDestroy(&st);
}
归并排序
void _MergeSort(int* a, int begin, int end, int* tmp)
{
if (begin >= end)
return;
int mid = (begin + end) / 2;
// [begin, mid] [mid+1, end] 递归让子区间有序
_MergeSort(a, begin, mid, tmp);
_MergeSort(a, mid+1, end, tmp);
// 归并[begin, mid] [mid+1, end]
//...
int begin1 = begin, end1 = mid;
int begin2 = mid+1, end2 = end;
int i = begin;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
tmp[i++] = a[begin1++];
}
else
{
tmp[i++] = a[begin2++];
}
}
while (begin1 <= end1)
{
tmp[i++] = a[begin1++];
}
while (begin2 <= end2)
{
tmp[i++] = a[begin2++];
}
memcpy(a + begin, tmp + begin, sizeof(int)*(end - begin + 1));
}
void MergeSort(int* a, int n)
{
int* tmp = (int*)malloc(sizeof(int)*n);
if (tmp == NULL)
{
perror("malloc fail");
exit(-1);
}
_MergeSort(a, 0, n - 1, tmp);
free(tmp);
tmp = NULL;
}
计数排序
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
void CountSort(int* a, int n)
{
int max = a[0], min = a[0];
for (int i = 1; i < n; ++i) {
if (a[i] < min)
min = a[i];
if (a[i] > max)
max = a[i];
}
int range = max - min + 1;
int* countA = (int*)calloc(range, sizeof(int));
if (countA == NULL)
{
perror("calloc fail\n");
exit(-1);
}
// 1、统计次数
for (int i = 0; i < n; ++i)
{
countA[a[i] - min]++;
}
// 2、排序
int k = 0;
for (int j = 0; j < range; ++j) {
while (countA[j]--)
{
a[k++] = j + min;
}
}
free(countA);
}
int main()
{
int a[10] = { 232,231,454,331,356,345,323,276,234,265 };
CountSort(a,10);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", a[i]);
}
return 0;
}