#include<stdio.h>
//排序分为插入排序,希尔排序,冒泡排序,快速排序,选择排序,堆排序,归并排序,基数排序(桶排序)
//1.1
//直接插入排序,较为简单,思路为从第二个数开始逐个将其插入前面有序的序列中
//平均时间复杂度为O(N2),最快时间复杂度为O(N),最坏时间复杂度为O(N2),空间复杂度为O(1)
void InsertSort(int *a,int n) {
int i;
for (i = 2; i <= n; i++)
{
if (a[i-1] > a[i]) {
int j = i - 1;
a[0] = a[i];
for (; j > 0 && a[j] > a[0]; j--) a[j + 1] = a[j];
a[j + 1] = a[0];
}
}
}
//1.2
//折半插入排序
//思路相同,查找方法改为折半查找插入位置
void BInsertSort(int *a, int n)
{
int i;
for (i = 2; i <= n; i++)
{
if (a[i - 1] > a[i])
{
a[0] = a[i];
int low = 1, high = i - 1;
while (low <= high)
{
int mid = (low + high)/2;
if (a[mid] > a[0]) high = mid - 1;
else low = mid + 1;
}
int j;
for (j = i - 1; j > high; j--) {
a[j + 1] = a[j];
}
a[j + 1] = a[0];
}
}
}
//1.3
//二路插入排序
//具体实现不再写,思路为设置一个头指针为较小的数,设置一个尾指针为较大的数,开始循环查找,若数比头指针小则插入头指针前,若比尾指针大
//则插入尾指针后,若在二者之间则利用二分查找找到合适的插入位置进行位置变换。
//1.4
//希尔排序思路与直接插入排序相似,加入步长概念,原理为排较为有序的序列时时间较短
//平均时间复杂度O(N1.3),空间复杂度为O(1)
void ShellInsert(int *a, int n, int dk)//一趟希尔插入排序,dk为步长
{
int i;
for (i = dk + 1; i <= n; i++)
{
if (a[i - dk] > a[i])
{
a[0] = a[i];
int j;
for (j = i - dk; j > 0 && a[j] > a[0]; j -= dk) a[j + dk] = a[j];
a[j + dk] = a[0];
}
}
}
void ShellSort(int *a, int n, int *dlt,int k)//按照增量为dlt[0...k-1]做一次希尔排序
{
int i = 0;
for (i = 0; i < k; i++)
{
ShellInsert(a, n, dlt[i]);
}
}
//2.1
//基于交换的排序,冒泡排序法
//平均时间复杂度为O(N2),最坏时间复杂度为O(N2),最好时间复杂度为O(N)
void BubbleSort(int *a, int length)//相当于每次将最大或最小的排到最后一个
{
for (int i = 0; i < length - 1; i++)
{
for (int j = 0; j < length - i - 1; j++)
{
if (a[j] > a[j + 1])
{
int temp;
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}
//2.2
//快速排序,设置low和high两个指针,每次排完后找到一个枢轴,使其左边为比它小的元素,右边为比它大的元素;
//再继续对其左边和右边执行这个过程
//平均时间复杂度和最好时间复杂度都为O(N*logN),最坏时间复杂度为O(N2)
int Partition(int *a, int left,int right)
{
int low = left, high = right;
int base=a[low];
while (low < high) {
while (low<high&&a[high]>=base) high--;
if (low < high) a[low] = a[high];
while (low < high&&a[low] <= base) low++;
if (low < high) a[high] = a[low];
}
a[low] = base;
return low;
}
void QSort(int *a, int left, int right) {
if (left < right) {
int pivotloc = Partition(a, left, right);
QSort(a, left, pivotloc - 1);
QSort(a, pivotloc + 1, right);
}
}
//3.1
//基于选择的排序
//选择排序,思路为每次循环找到最小的并将其放在数组头处
//平均复杂度O(N2),最坏情况O(N2),最好情况O(N)
void SelectSort(int *a, int n)
{
int i, j;
int min, temp;
for (i = 0; i < n-1; i++)
{
min = i;
for (j = i; j < n; j++)
{
if (a[j] < a[min]) min = j;
}
temp = a[min];
a[min] = a[i];
a[i] = temp;
}
}
//3.2
//堆排序 思路:建立堆,初始化堆,每次输出堆顶后将最后一个节点与堆顶互换,重新调整堆
//该排序为从小到大排序
//平均最坏最好时间复杂度都为O(N*logN)
typedef struct Heap {
int length;
int *elem;
}Heap;
void HeapAdjust(Heap H,int s,int m)//调整使其成为一个大顶堆
{
int largest;
int temp;
int lc = 2 * s;
int rc = lc + 1;
if (H.elem[lc] > H.elem[s] && lc <= m) largest = lc;
else largest = s;
if (H.elem[rc] > H.elem[largest] && rc <= m) largest = rc;
if (largest != s)
{
temp = H.elem[largest];
H.elem[largest] = H.elem[s];
H.elem[s] = temp;
HeapAdjust(H, largest, m);
}
}
void HeapSort(Heap H)
{
int i, temp;
for (i = H.length / 2; i > 0; i--)
{
HeapAdjust(H, i, H.length);
}//初始化堆
for (i = H.length; i > 1; i--)
{
temp = H.elem[1];
H.elem[1] = H.elem[i];
H.elem[i] = temp;
HeapAdjust(H, 1, i-1);
}//将堆顶和最后一个互换位置,然后对前i-1个元素重新调整
}
//4.1
//归并排序,平均最好最坏时间复杂度都为O(N*logN)
//思路对每一部分进行排序,使用的思想是归并思想,利用分治的策略解决问题
//重复比较加填入的方法
int main()
{
int a[11] = { 0,3,1,3,2,4,5,6,1,7,13 };
/*InsertSort(a, 10);*/ //插入排序测试
/*BInsertSort(a, 10);*/ //二分插入排序测试
/*int dlt[4] = { 4,3,2,1 }; //希尔排序测试
ShellSort(a, 10, dlt, 4);*/
/*BubbleSort(a + 1, 10);*/ //冒泡排序测试
/*QSort(a, 1, 10);*/ //快排测试
/*SelectSort(a+1, 10);*/ //选择排序测试
/*Heap H; //堆排序测试
H.elem = a;
H.length = 10;
HeapSort(H);*/
for (int i = 1; i < 11; i++)
printf("%d ", a[i]);
}
C语言实现各种排序(1)
猜你喜欢
转载自blog.csdn.net/weixin_43889775/article/details/85037519
今日推荐
周排行