A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 后知后觉4778 中级黑马   /  2015-12-23 21:52  /  2999 人查看  /  20 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

首先排序的对用对象是数组,可以是整型数组,也可以是字符数组,甚至可以是字符串数组,这里以int数组为例,假设定义数组int  a[6] = {23,78,34,89,12,45},排序无外乎就是遍历数组元素,比较元素,交换元素。很多人感觉冒泡排序和选择排序是一样的,其实不然,我在这先写一下思想,然后比照代码可以更好的理解
冒泡排序的思想是:
                 在第1趟遍历中,依次比较相邻的两个数组元素(如a[0]和a[1],a[1]和a[2],a[2]和a[3],a[3]和a[4]………)让相邻两个元素中较大的值放在下标较大的位置,如:若a[0]>a[1],则交换两个元素,让较大的值放在a[1],否则不交换,若a[1]>a[2],则交换两个元素,让较大的值放在a[2],交换后a[2]和a[3]重复上述操作,让a[2]和a[3]中较大的值放到a[3],到此a[3]中存放的是a[0],a[1],a[2]和a[3]中的最大值,然后继续a[3]和a[4],a[4]和a[5],第一趟结束后,数组中的最大值已经移动到a[5];即较大的数沉底,较小的数上浮,所以叫冒泡排序
                  然后进行第2趟遍历,从a[1到a[4],因为在第1趟中已经确定了最大值,并且放到了a[5],所以不用在比较a[5]了,第2趟结束后,把次大值放到了a[4]中。
                  第3趟: 遍历a[0],a[1],a[2],a[3],然后确定其中的最大值放到a[3]中,同理
               第4趟: 确定a[0],a[1],a[2]中的最大值放到a[2]中。
               第5趟: 确定a[0],a[1]中的最大值放到a[1]中,这样剩下的a[0]自然是6个数中的最大值,至此排序
                结束,共遍历数组5趟,第i趟遍历前6-i个元素,确定6-i个元素的最大值,交换到a[6-i-1].
               代码如下:
               
        /*
         冒泡排序:
                冒泡排序的实现方式大体上有两种:大数下沉和小数上浮,本例实现方法时小数上浮
                1,和选择排序一样比较n-1趟,每一趟遍历前n-i个元素,找出最小的元素放到下标为n-i-1的位置
                2,比较是相邻两个元素比价,让比较小得元素移动到两个元素下标大的地方,这样每一趟结束,都是当前无序数的最小值
         */
       
        /*
         选择排序和冒泡排序的区别:
            1,选择排序是某个数依次和其他没有序的人依次比较,冒泡的每一趟都是相邻的两个数比较
         */
       
        # include <stdio.h>
        int main()
        {
            void sort(int array[],int length);
            void sort2(int array[],int length);
            int a[10]={12,23,34,45,56,67,78,89,90,100};
            //sort(a,10);
            sort2(a,10);
            for(int i=0;i<10;i++)
                printf("%d ",a[i]);
            printf("\n");
            return 0;
        }
        void sort(int array[],int length)
        {
            int i,j,temp;
            for(i=0;i<length-1;i++)
                //
                for(j=0;j<length-i-1;j++)
                    if(array[j]<array[j+1]) // 小数上浮
                    {
                        temp = array[j];
                        array[j] = array[j+1];
                        array[j+1] = temp;
                    }
                   
        }
        void sort2(int array[],int length)
        {
            int i,j,temp;
            for(i=0;i<length-1;i++)
                //
                for(j=length-i-1;j>0;j--)
                    if(array[j] > array[j-1]) // 大数下沉
                    {
                        temp = array[j];
                        array[j] = array[j-1];
                        array[j-1] = temp;
                    }
            
        }
       
选择排序的思想是:
                在第1趟遍历中,让第一个元素即a[0],依次与数组的其他元素(a[1],a[2],a[3],a[4],a[5])比较,若发现有元素比a[0]小,则立即交换,让较小的元素和a[0],这样第1趟结束后,a[0]存放的就是数组的最小值。
               
                第2趟:因为已经确定了a[0]是数组6个元素的最小值,所以从a[1]开始往后遍历,确定a[1],a[2],a[3],a[4],a[5]中的最小值,然后放到a[1]中
                第3趟:同理,遍历a[2],a[3],a[4],a[5],确定其中的最小值放到a[2]中。
                第4趟:同理,遍历a[3],a[4],a[5],确定其中的最小值放到a[3]中。
                第5趟:同理,遍历a[4],a[5],确定其中的最小值放到a[4]中,自然剩下的肯定是数组元素的最大值了,不用在参与比较
                同样,进过5趟比较后,数组元素已经有序,并且是由大到小,实现代码如下:
                void sort2(int array[],int length)
                {
                    int i,j,k,temp;
                    for(i=0;i<length-1;i++)
                    {
                        for(j=i+1;j<length;j++)
                            if(array[j]>array[i])
                            {
                                temp = array[i];
                                array[i] = array[j];
                                array[j] = temp;
                            }
                    }
                }
               
改进的选择排序算法:若上述两个排序方法已经掌握,我再给大家说一个改进的选择排序算法:
               
                void selectSort2(int array[],int length)
                {
                    int i,j,k,temp; //定义用于交换的变量temp
                    for(i=0;i<length-1;i++)
                    {
                        k = i;//记录当前乱序的最大值的下标
                        for(j=i+1;j<length;j++)
                            if(array[j]>array[i])
                                k = j;//发现数据比最大值大,更新下标
                        if(i!=k) // 若i!=k,说明假定的最大值很真实的最大值下标不一样,交换,若一样就不用交换了
                        {
                            temp = array[i];
                            array[i] = array[k];
                            array[k] = temp;
                        }
                    }
                }
                这种方式不像上述选择排序一样,一发现比较小的值就交换,而是额外定义一个变量,存储当前趟遍历元素的最小值的下标,在一趟中每次若发现较小的值,则更新下标变量为较小值的下标,然后在一趟遍历结束的时候,把下标变量记录的元素与第i个元素交换。这样的话可以减少交换的次数,在一定程度上降低了算法的复杂度。


评分

参与人数 1黑马币 +2 收起 理由
junjunzhang + 2 赞一个!

查看全部评分

20 个回复

倒序浏览
很好,很透彻
回复 使用道具 举报
楼主我正好在学这里
回复 使用道具 举报
很好 我正学到这里
回复 使用道具 举报
看看 看看
回复 使用道具 举报
很好,顶一个
回复 使用道具 举报

谢谢   相互交流{:2_36:}
回复 使用道具 举报
holmesconan 发表于 2015-12-24 09:42
楼主我正好在学这里

安卓还是IOS 可以交流一下
回复 使用道具 举报
后知后觉4778 发表于 2015-12-24 22:38
安卓还是IOS 可以交流一下

iOS 呀~~~
回复 使用道具 举报
你的这个改正算法思想是好的,但是你的代码实现不了呢
回复 使用道具 举报
HHE_johnson 发表于 2015-12-25 21:24
你的这个改正算法思想是好的,但是你的代码实现不了呢

是的 代码复制错了 看看这个
  1. void sort(int array[],int length)
  2. {
  3.     int i,j,k,temp;
  4.     for(i=0;i<length-1;i++)
  5.     {
  6.         k = i;
  7.         for(j=i+1;j<length;j++)
  8.             if(array[j]>array[k])
  9.                 k = j;
  10.         if(i!=k)
  11.         {
  12.             temp = array[i];
  13.             array[i] = array[k];
  14.             array[k] = temp;
  15.         }
  16.     }
  17. }
复制代码
回复 使用道具 举报
后知后觉4778 发表于 2015-12-25 22:30
是的 代码复制错了 看看这个

赞,这位兄弟对排序法理解得很透彻了!
回复 使用道具 举报
yolande 来自手机 中级黑马 2015-12-26 20:26:20
13#
你还可以去了解一下优化,用哨兵
回复 使用道具 举报
精诚 中级黑马 2015-12-27 11:05:02
14#
正需要那,谢谢
回复 使用道具 举报
表示必须得练习才行啊
回复 使用道具 举报
楼主6666,分析透彻
回复 使用道具 举报
zf147 中级黑马 2015-12-29 23:24:39
17#
很好 我正学到这里
回复 使用道具 举报
不赖  很详细 有解释 有代码 不赖
回复 使用道具 举报
学习学习!
回复 使用道具 举报
感觉老师讲这个也老讲不清楚
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马