选择排序的优化c语言,C语言 五种排序方式

本文详细介绍了数据结构中的五种排序算法:冒泡排序、直接选择排序、直接插入排序、快速排序和二路归并排序。通过C语言代码展示了每种排序算法的实现,并分析了它们的稳定性及平均时间复杂度。冒泡排序和插入排序是稳定的,平均时间复杂度为O(n^2),而选择排序和快速排序不稳定,同样具有O(n^2)的时间复杂度。归并排序则是稳定的,平均时间复杂度为O(log2n)。
摘要由CSDN通过智能技术生成

这几天看了郝斌的数据结构视频,对于各种排序方式有了更深刻的理解。下面与大家分享下我的学习成果,不足之处忘指正。

PS:博文中的代码都是自己敲的,便于理解。

这里讲的五种排序方式,是指冒泡排序、直接选择排序、直接插入排序、快速排序以及二路归并排序。

冒泡排序:排序的思路正如“冒泡”二字,每次比较第i和i+1个位置的值,若a[i]>a[i+1],则交换。这样第一趟下来,最大的数在第n-1个位置;第二趟下来,次最大的数在第n-2个位置,依此类推,直到所有的数排序完毕。

C语言的代码为(p指向数组首元素,len表示数组元素的个数):void bubbleSort(int *p, int len)

{

int i = 0;

int j = 0;

int temp = 0;

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

{

for (j = 0; j < len-1-i; j++)

{

if (p[j] > p[j+1])

{

temp = p[j];

p[j] = p[j+1];

p[j+1] = temp;

}

}

}

}

冒泡排序是稳定的,平均时间复杂度为o(n2)

直接选择排序。若是从小到大排序,则第1趟把最小的值放在第0个位置,第2趟把次最小值放在第1个位置,依此类推,直到所有的数排序完毕。

c语言代码为:void selectSort(int *p, int len)

{

int i = 0;

int j = 0;

int temp = 0;

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

{

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

{

if (p[j] < p[i])

{

temp = p[i];

p[i] = p[j];

p[j] = temp;

}

}

}

}

直接选择排序是不稳定的算法,平均时间复杂度也是o(n2)。看到网上很有人认为选择排序是稳定的算法,其实不然,例如5,3,5,2,1。第一趟排序完后,第一个5与最后的1交换,位置为2的5自然在原本位置为0的5的前面了。

直接插入排序。假定前i个数已经有序,直接插入排序是把第i+1个数插入到前i个数中的合适位置,重新组成大小为i+1个数的有序序列。

C语言实现代码:void insertSort(int *p,int len)

{

int i = 0;

int j = 0;

int temp = 0;

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

{

temp=p[i];

for (j = i; j > 0 && temp < p[j-1]; j--)

{

p[j] = p[j-1];

}

p[j] = temp;

}

return;

}

直接插入排序是稳定的,平均时间复杂度也是o(n2)。

快速排序。快速排序采用递归思想,速度自然快很多。假定有n个数,参考值value,也就是我们的比较对象为数组的第一个元素,那么一趟快速排序后,value左侧的值都比value小,右侧的值都比value大。然后再按此方法对这两部分数据分别进行快速排序,依此类推,直到整个数据变成有序序列。

C语言代码如下:void quickSort(int *p,int low ,int high)

{

int posi = 0;

if (high > low)

{

posi = findPosi(p,low,high);

if (posi > low){

quickSort(p,low,posi-1);

}

if (posi < high){

quickSort(p,posi+1,high);

}

}

}

int findPosi(int *p,int low,int high)

{

int value = *(p+low);

while (high > low)

{

while(p[high] >= value && high > low)

{

high--;

}

p[low] = p[high];

while (p[low] <= value && low < high)

{

low ++;

}

p[high] = p[low];

}

p[low] = value;

return low;

}

快速排序是不稳定的,平均时间复杂度是o(log2n)。

最后是归并排序。二路归并排序的思想是分而治之,即divide and conquer。divide:不断地拆分数组,直到每个数组都只有一个元素。conquer:并,把拆分后的数组按关键字排序,不断合并,直到整个数据有序。很明显,二路归并排序利用了递归的思想。

下面给出它的C语言实现:void divide(int *p,int low,int high){

int mid = (low + high)/2;

if (low < high){

divide(p,low,mid);

divide(p,mid+1,high);

}

GuiBingSort(p,low,mid,high);

}

void GuiBingSort(int *p,int low,int mid, int high){

int leftIndex = low;

int rightIndex = mid+1;

int tempIndex = 0;

int tempLen = high-low+1;

int *temp = (int *)malloc(sizeof(int)*(tempLen));

if (NULL == temp){

printf("分配内存失败!\n");

return;

}

while(leftIndex <= mid && rightIndex <= high){

if (p[leftIndex] <= p[rightIndex]){

temp[tempIndex] = p[leftIndex];

leftIndex++;

}else{

temp[tempIndex] = p[rightIndex];

rightIndex++;

}

tempIndex++;

}

if (leftIndex > mid){

while(rightIndex <= high){

temp[tempIndex] = p[rightIndex];

rightIndex++;

tempIndex++;

}

}else if (rightIndex > high){

while (leftIndex <= mid){

temp[tempIndex] = p[leftIndex];

leftIndex++;

tempIndex++;

}

}

int i = 0;

for (i = 0; i < tempLen; i++ ){

p[i+low] = temp[i];

}

free(temp);

return;

}

归并排序是稳定的,平均时间复杂度是o(log2n)。

最后附上main函数的代码:int main()

{

int a[7] = {1,5,4,89,23,100,-3};

int len = sizeof(a)/sizeof(int);

// printf("插入排序之后\n");

//insertSort(a,len);

showArray(a,len);

// printf("选择排序之后\n");

// selectSort(a,len);

showArray(a,len);

// printf("冒泡排序之后:\n");

//bubbleSort(a,len);

showArray(a,len);

// printf("快速排序之后\n");

// quickSort(a,0,len-1);

showArray(a,len);

printf("归并排序之后\n");

divide(a,0,len-1);

showArray(a,len);

return 0;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值