c语言数组常用,常用排序算法总结(简单数组实现,其他类似)----- C语言

排序是计算机内经常进行的一种操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。分内部排序和外部排序。若整个排序过程不需

要访问外存便能完成,则称此类排序问题为内部排序。反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问

题为外部排序。内部排序的过程是一个逐步扩大记录的有序序列长度的过程。

我们这里说的是内部排序。

3ba1c2fd8c15b974151e191bb70e622c.png

勘误 : 选择排序是不稳定的 !!!

/*

*

*各类排序算法复习(简单数组实现,其他类似)

*Sort Type Review

*2015.11.09

*By Snow Yong

*

*/

#define MINIMUMSIZE 7 //快速排序自定义小数组数目

#define A_LENGTH 10 //数组长度

#include int Swap(int *a, int i, int j);

int BubbleSort(int *a);

int SelectSort(int *a);

int InsertSort(int *a);

int ShellSort(int *a);

int HeapSort(int *a);

int HeapAdjust(int *a, int low, int high);

int MergeSort(int *a);

int Msort(int *S, int *T, int low, int high);

int Merge(int *S, int *T, int low, int m, int high);

int QuickSort(int *a);

int Qsort(int *a, int low, int high);

int Partition(int *a, int low, int high);

int PickMiddle(int *a, int low, int high);

/* Swap Function using to swap element

*元素交换函数

*/

int Swap(int *a, int i, int j)

{

int temp;

temp = a[i];

a[i] = a[j];

a[j] = temp;

}

//BubbleSort -- 冒泡排序 O(n^2)

int BubbleSort(int *a)

{

/*

*flag is using for sort flag

*flag变量用于提高冒泡效率

*/

int i, j, flag = 1;

for (i = 0; i < A_LENGTH-1 && flag; i++)

{

flag = 0;//若flag经 j 循环后为0,则说明序列已然有序

for (j = A_LENGTH-1; j > i; j--)

{

if (a[j] < a[j-1])

{

Swap(a, j, j-1);

flag = 1;

}

}

}

}

//SelectSort -- 选择排序 O(n^2)

int SelectSort(int *a)

{

int i, j, min;

for (i = 0; i < A_LENGTH-1; i++)

{

min = i;

for (j = i+1; j < A_LENGTH; j++)

{

if (a[min] > a[j])

{

min = j;/*不直接交换值,而是记录下标*/

}

}

//若下标不同再一次替换成最小值

if (min != i)

{

Swap(a, min, i);

}

}

}

//InsertSort -- 插入排序 O(n^2)

int InsertSort(int *a)

{

int i, j, temp;

//从第二个数开始循环

for (i = 1; i < A_LENGTH; i++)

{

//满足前提的条件下再记录a[i]的值

if (a[i] < a[i-1])

{

temp = a[i];

for (j = i-1;

a[j] > temp && j >= 0;

j--)

{

a[j+1] = a[j];

}

a[j+1] = temp;/*此处为a[j+1]而不是a[j]是因为上面循环最后执行了j--*/

}

}

}

//ShellSort -- 希尔排序 O(n^(3/2))

int ShellSort(int *a)

{

int i, j, temp;

int increament = A_LENGTH;/*类似插入排序,increament增量处理*/

//跳跃式插入排序

do

{

increament = increament/3 + 1;

for (i = 0+increament; i < A_LENGTH; i++)

{

if (a[i] < a[i-increament])

{

temp = a[i];

for (j = i-increament;

a[j] > temp && j >= 0;

j -= increament)

{

a[j+increament] = a[j];

}

a[j+increament] = temp;

}

}

}

while (increament > 1);

}

//HeapSort -- 堆排序 O(nlogn)

int HeapSort(int *a)

{

int i;

//自行查阅堆和大(小)顶堆的定义

//初始化从中间位置开始构造大顶堆

for (i = A_LENGTH/2 - 1; i >= 0; i--)

{

HeapAdjust(a, i, A_LENGTH-1);

}

//此处一边将最大值选出,一边重新从 0 到 i-1 下标调整大顶堆

for (i = A_LENGTH - 1; i > 0; i--)

{

Swap(a, 0, i);

HeapAdjust(a, 0, i-1);

}

}

//该函数为堆的调整函数(将序列调整为大顶堆), 核心实现函数

int HeapAdjust(int *a, int low, int high)

{

int i, j, temp = a[low];

for (i = 2*low + 1; i <= high; i = 2*i + 1)

{

if (i < high && a[i] < a[i+1])

{

i++;

}/*左右孩子值比较取其较大者*/

if (temp >= a[i])

{//父节点值不小于孩子节点值

break;

}

a[low] = a[i];

low = i;/*不断将下标替换较大值的孩子的下标*/

}

a[low] = temp;

}/*此函数用于调整排序序列为大顶堆*/

//MergeSort -- 归并排序(递归式) O(nlogn),

//非递归的归并算法请参考博文 ”非递归 -- 归并排序(C语言)“ ,注:一般推荐采用非递归的归并算法

int MergeSort(int *a)

{

Msort(a, a, 0, A_LENGTH-1);

}

int Msort(int *S, int *T, int low, int high)

{

int m;

int T_temp[A_LENGTH];/*辅助数组*/

if (S[low] == S[high])

{

T[low] = S[low];

}

else

{

m = (low + high) / 2;

Msort(S, T_temp, low, m);

Msort(S, T_temp, m+1, high);

Merge(T_temp, T, low, m, high);

}

}

int Merge(int *S, int *T, int low, int m, int high)//归并主要实现函数

{

int j, k, l;/*k用于T数组的下标前进*/

for (k = low, j = m+1;

low <= m && j <= high;

k++)

{

if (S[low] < S[j])

{

T[k] = S[low++];

}

else

{

T[k] = S[j++];

}

}

if (low <= m)

{

for (l = 0; l <= m-low; l++)

{

T[k+l] = S[low+l];

}

}

if (j <= high)

{

for (l = 0; l <= high-j; l++)

{

T[k+l] = S[j+l];

}

}

}

//QuickSort -- 快速排序(已优化) O(nlogn)

int QuickSort(int *a)

{

Qsort(a, 0, A_LENGTH-1);

}

int Qsort(int *a, int low, int high)

{

int pivot;/*枢轴值*/

if ((high - low) > MINIMUMSIZE)

{

while (low < high)

{

pivot = Partition(a, low, high);

Qsort(a, low, pivot-1);

low = pivot + 1;/*此处优化Qsort(a, pivot+1, high)的尾递归*/

}

}

else/*优化小数组的处理方式 -- 变为插入排序效率更高*/

{

InsertSort(a);

}

}

//此处为求枢轴的函数

int Partition(int *a, int low, int high)

{

int temp;

PickMiddle(a, low, high);/*经此函数保证a[low]为较接近中间值*/

temp = a[low];

while (low < high)

{

while (low < high && a[high] >= temp)

{

high--;

}

a[low] = a[high];/*此处优化不必要的交换*/

while (low < high && a[low] <= temp)

{

low++;

}

a[high] = a[low];/*此处优化不必要的交换*/

}

a[low] = temp;

return low;

}

//取接近序列中间大小值并交换给a[low]的函数

int PickMiddle(int *a, int low, int high)

{

int m = (low + high) / 2;

if (a[low] > a[high])

{

Swap(a, low, high);

}

if (a[m] > a[high])

{

Swap(a, m, high);

}

if (a[low] > a[m])

{

Swap(a, low, m);

}

}

int main()

{

int i;

int a[A_LENGTH] = {50, 90, 80, 40, 30,

70, 60, 10, 20, 100};

printf("Before sorting:");

for (i = 0; i < A_LENGTH; i++)

{

printf("%d -- ", a[i]);

}

// BubbleSort(a);

// SelectSort(a);

// InsertSort(a);

// ShellSort(a);

// HeapSort(a);

// MergeSort(a);

QuickSort(a);

printf("\n\nAfter sorting: ");

for (i = 0; i < A_LENGTH; i++)

{

printf("%d -- ", a[i]);

}

return 0;

}

运行结果就不上图了,跟其他排序详解都差不多,因为不喜欢VS卡又慢,所以平台是win + notepad++,编译用的是 MinGW 的 gcc ,因为懒得开虚拟机运行CentOS,

大概结果可参考其他排序算法详解,能力有限,谢谢阅读!

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。

快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值