排序(中)---选择、冒泡

排序(中)—选择、冒泡

选择排序

简单来说就是众神归位法,每一趟排序都会选出一个最大的和一个最小的数据,并放在该放的位置上。

由小到大进行排序:

  1. 遍历整个数据,选出最大的数据(下标),与最后一个下标的数据进行交换,数组的大小减一。
  2. 遍历剩余的数据,选出最大的数据(下标),与最后一个剩余数据的最后一个下标的数据进行交换。
  3. 直到剩余的数据中只有一个元素,排序完成。
  4. 时间复杂度都是O(n^2)

流程图:
选择排序

代码:

//选择排序
void SelectSort(int arr[], int size)
{
    int maxIndex = 0;
    int endIndex = 0;
    int i = 0;
    for (endIndex = size-1; endIndex>=0; endIndex--)//每次交换之后都会让数据的元素个数减少一个
    {
        for (i = 0,maxIndex = 0; i<=endIndex; i++)
        {
            if (arr[i] > arr[maxIndex])//让maxIndex始终指向最大的数据
            {
                maxIndex = i;
            }
        }
        //已经找到,进行交换
        int tmp = arr[endIndex];
        arr[endIndex] = arr[maxIndex];
        arr[maxIndex] = tmp;
    }
}

上面的代码是一次性找出一个最大的数,每次选出最大的数都需要n次,但是我们可以简单的修改一下代码让其循环次数更小,思想是每次找出一个最大的和一个最小的,将最大的放在后面,将最小的放在最前面,这样数据元素的个数每次都要减少2.

代码:

//选择排序升级版
void SelectSortPlus(int arr[], int size)
{
    int maxIndex = 0;//代表最大数的下标
    int minIndex = 0;//最小数的下标
    int startIndex = 0;//每次循环的开始下标
    int endIndex = size - 1;//每次循环的截止下标
    int i = 0;
    for (;startIndex <= endIndex; startIndex++,endIndex--)
    {

        for (i=startIndex,maxIndex = startIndex, minIndex = startIndex;  i<=endIndex; i++)
        {
            if (arr[i] > arr[maxIndex])
            {
                maxIndex = i;
            }
            else if (arr[i] < arr[minIndex])
            {
                minIndex = i;
            }
        }
        //交换的时候如果某一次最小的值的下标在循环的截止下标
        //那么此时就应该先将最小的交换至开始循环的位置
        if(minIndex == endIndex)
        {
            Swap(arr+minIndex, arr+startIndex);//Swap的实现就不用实现了吧
            Swap(arr+maxIndex, arr+endIndex);
        }
        else//否则就应该先交换最大的值
        {
            Swap(arr+maxIndex, arr+endIndex);
            Swap(arr+minIndex, arr+startIndex);
        }
    }
}

这样大大减少了总的循环次数

冒泡排序

世界上最简单的排序算法,思路是从一组数据的第一个数据开始,将较大(或者较小)的数据一步一步推向最后一个位置


  1. 从第一个数据开始进行比较,与其后面的进行比较,如果大于其后面的数,那就进行交换。
  2. 向后偏移,从第二个数据开始,因为刚才的比较和交换,现在第二个数是前两个数种最大的,然后再将第二个数与第三个数进行比较,然后同上。
  3. 当排到倒数第二个数的时候,就说明已经将整个数据种最大的数推到了最后一个位置。
  4. 然后进行第二次排序,选出倒数第二个,倒数第三个……
  5. 每一趟循环之后,下一次循环可以排到上次排过的数的前面,这样每一趟循环,下一趟就会少次比较。
  6. 时间复杂度:
    • 最好O(n)
    • 最坏O(n^2)

代码:
//冒泡排序
void BubbleSort(int arr[], int size)
{
    int endIndex = 0;
    int i = 0;
    for (endIndex=size-1; endIndex>=0; endIndex--)
    {
        for (i=0; i < endIndex; i++)
        {
            if (arr[i] > arr[i+1])
            {
                int tmp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = tmp;
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值