排序算法之选择排序

      我们经常能遇到这样的问题,让你对一串数据进行排序,比如对一个数组,对顺序表等等进行排序。排序的方法有很多,你可以任意选择,只要能达到人家所要求的效果。一说到排序,对我来说最熟悉的就是冒泡排序,对于冒泡排序只要你掌握好了两个循环的条件其实很简单,今天我们谈谈另外一种排序算法:选择排序。

       首先我们来说说选择排序的原理,我们还是要用两层for循环,外循环代表循环的次数,内循环是每次循环进来还要比较的次数。请看下面的图:首先我们把数组的第一个位置也就是位置0设为maxpos和minpos,然后再用一个循环进行数组内内容的比较,如果有比maxpos位的数大的,则更正我们的maxpos,这样比较完一次我们可以找到存最大的数的一个位置,比如下图中,我们最后找到了存放5的位置,也就是位置4,则maxpos=4.

       我下面的程序是改进了之后的选择排序,就是在进行比较的时候,同时更正minpos的值,这样我们的外层循环就被简化为原来次数的一半。如果不加改进其实写起来很简单,只需要定一个maxpos就够了。在这里就不写了。

       当一次比较完成后,我们就进行交换,假如现在是升序排序。把maxpos上的值和最右边位置的值进行交换,把minpos上的值和最右边位置的值进行交换。从而达到排序的效果。

 

 

       

         但是我这样优化了之后也会存在一个问题,就是一次更正后要对maxpos上的值和minpos上的值分别交换到需要的位置上,那么如果刚好我maxpos上的值要交换的位置刚好就是我的minpos,那么我们在交换的时候就会把本来minpos上的值换走了,等你在对minpos上的值进行移动的时候肯定就不是我们想要的结果了。比如下面的情况:内循环完成之后,得到的maxpos是0,minpos是3,然后如果不进行别的处理,最大值5要被我和最右边位置的1进行交换,之后minpos上的值就变成5了,接下来的交换肯定就不对了。

                             

         所以在进行交换前我们就要进行判断,如果存在这样的问题,就把此时的maxpos和minpos上的值交换,同时也把minpos和maxpos进行交换。

        下面是选择排序的程序代码,红色部分就是判断上面所述的特殊情况进行的处理。自己写的,肯定有很多地方比较麻烦希望见谅,大家有什么好的建议可以提出。

复制代码
 1 #define  _CRT_SECURE_NO_WARNINGS
 2 #include <stdio.h>
 3 #include<assert.h>
 4 #include<string.h>
 5 #include<windows.h>
 6 
 7 void selectsort(int *str,int len)
 8 {
 9     int maxpos = 0;
10     int minpos = 0;
11     int i = 0,j = 0;
12     assert(str);
13     for (; i < len / 2; i++)
14     {
15         maxpos = i, minpos = i;
16         for (j = i + 1; j < len-i; j++)
17         {
18             if (str[j]>str[maxpos])
19                 maxpos = j;
20             if (str[j] < str[minpos])
21                 minpos = j;
22         }
23         if (len - i - 1 == minpos)
24         {
25             int tmp = str[maxpos];
26             int tmp1 = maxpos;
27             str[maxpos] = str[minpos];
28             str[minpos] = tmp;
29             maxpos = minpos;
30             minpos = tmp1;
31         }
32         if (len - i - 1 != maxpos)
33         {
34             int temp = str[maxpos];
35             str[maxpos] = str[len - i - 1];
36             str[len - i - 1] = temp;
37         }
38         if (i != minpos)
39         {
40             int temp1 = str[minpos];
41             str[minpos] = str[i];
42             str[i] = str[minpos];
43         }
44     }
45 }
46 
47 int main()
48 {
49     int i = 0;
50     int str[] = { 1, 3, 4, 7, 2, 4, 6, 8 };
51     int len = sizeof(str) / sizeof(str[0]);
52     selectsort(str,len);
53     for (; i < len; i++)
54     {
55         printf("%d ", str[i]);
56     }
57 
58     system("pause");
59     return 0;
60 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值