冒泡排序,插入排序,选择排序

本文详细介绍了冒泡排序、插入排序和选择排序的基本原理和区别。冒泡排序通过相邻元素比较交换逐步减少排序次数;插入排序在逐步增加的比较次数中确定元素位置;选择排序则逐步找出最小元素并排列。三种排序算法的时间复杂度均为O(n^2),空间复杂度为O(1)。此外,文章还讨论了算法的优化策略,如冒泡排序中的提前结束条件和插入排序的二分查找应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@TO冒泡排序,插入排序,选择排序C


冒泡排序,插入排序,选择排序

简要概述

1.冒泡排序

将相邻的元素,第一次必将会便利整个数组。当发现第一个元素大于第二个元素,那就进行交换。逐渐比较循环的次数减少。

2.插入排列

先假定第一个元素是“有顺序的”,之后让他与第二个元素进行比较,如果小于(整个序列按从小到大排列)第一个元素时,则排列在其之前,反之,排在之后。然后将他俩看做一个整体,之后的元素与这个整体中的元素从后往前一次比较,如果小则向前一位继续比较,如果大于则在该位置”插入“。该排列方法排列次数会逐步增加。

3.选择排序

将第一个元素设置为“最小元素”,之后将余下的元素和这个“最小元素”比较,如果小于“最小元素”,则与其调换下标,反之,进行下一元素比较。知乎每次比较上一次选中的“最小元素”固定,然后逐步往下进行。该排列方法会逐渐减少排列次数。

一、三种排序的区别

(1)次数

插入排序的排列次数是逐步增加(但会出现有部分可能次数也很少,但整体趋势是逐步增加)。而冒泡排序和选择排序的排列次数是逐步减少的,因为对于会有一部分“有顺序的”和一部分“没有顺序的”,而“没有顺序的”会根据排列逐步减少。

(2)排列方法

冒泡排序
因为相互之间要交换、比较,逐步将“较小的”元素排列在前端,将“较大的元素”排列在后端。所以第一次所有元素两两比较完成后,最大的元素就会排列在最后。之后每一步会将遍历过的元素中最大的元素排在可动范围内的最后。

选择排序
在第一次所有元素遍历借书后,就将最小元素排列在第一位,之后通过每次对剩下元素“比小”,找出“最小元素”放在之后。

插入排序而插入排序会通过第一次比较(及第一个元素和第二个元素进行大小比较),定下一个有“上限”和“下限”的“范围”,之后将剩余元素依次加入、比较(包括比较“上限”和“下限”)。

二、算法的优化

1.冒泡排序

在冒泡排序的最后两轮时,“无序”的部分其实就只剩下两个元素,而这两个元素在之前的排序中早已变成有序的,但因为循环退出条件是次数大于数组长度,所以算法依旧在执行,我们就可以将循环推出条件变成

for(int i = 0 ; i < array.length - i - 1 ; i ++)

在部分元素进行“交换”的时候,我们发现其实有一些元素原本就比之后元素小,所以虽然循环依旧在进行,但数据并未产生交换,这个时候会浪费资源。随意我们可以在交换的循环中添加一个标记<exchange = true>,表示此时有元素进行交换,所以是无序的。而元素因为没有产生交换时没进入该循环时,标识<exchange = false>,则跳出循环节省资源。

for( int i = 0 ; i < array.length - 1 ; i++ ) {
    		boolean exchange = false;
            System.out.printf( "第%d轮\n" , i + 1 );
            for (int j = 0; j < array.length - 1 - i ; j++) {
                if (array[j] > array[j + 1]) {
                    array[j] ^= array[j + 1];
                    array[j + 1] ^= array[j];
                    array[j] ^= array[j + 1];
                    exchange = true ; 
                }
                System.out.println("\t" + Arrays.toString(array));
            }
    if(exchange){
        break;
    }
        }

2.选择排序

最初的选择排序我们在排列时定义了一个最小值,让该值和其他元素进行比较,最后得出最小值放在第一位。那么根据这个思路,我们可以定义一个最大值,和最小值的思路一样,让他和其他值进行比较,最后将得出的值放在最后。

while (left < right)
    {
    //定义最小值放在左边,最大值放在右边
        int min = left;
        int max = right;
        for (int i = left; i <= right ; i++)
        {
            //同时进行最大值最小值比较
            if (arr[i] < arr[min])
                min = i;
            if(arr[i] > arr[max])
                max = i;
        }

2.插入排序

因为插入排序是将”无序“部分中的元素排列进之前排列好的“有序”部分中,每次对于对该部分的元素一次对比,所以我们可以通过二分法进行对比。

int i, j, temp, m, low, high;
        for (i = 1; i < len; i++)
        {
               temp = arr[i];
               low = 0; high = i-1;
               while (low <= high)
               {
                  m = (low +high) / 2;
                  if(arr[m] > temp)
                     high = m-1;
                  else
                     low = m+1;
               }
               for (j = i-1; j>=high+1; j--)
                    arr[j+1] = arr[j];
               arr[j+1] = temp;
       }

三.时间复杂度和空间复杂度

1、冒泡排序的空间复杂度和时间复杂度

时间复杂度:O(n^2)

空间复杂度:O(1)

2、插入排序的空间复杂度和时间复杂度

时间复杂度:O(n^2)

空间复杂度:O(1)

3、选择排序的空间复杂度和时间复杂度

时间复杂度:O((n*(n-1) ) / 2)

空间复杂度:O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值