冒泡排序法,选择排序法,直接插入法 --- 排序算法1

 冒泡排序法,时间复杂度O(n^2), 相邻元素依次比较, 较大的数字上升, 较小的数字下降, 

- (void)sortAction {
    //冒泡排序,相邻元素依次比较,把较大的数字上升,较小的数字下降,
    int num = 200;
    int a[num];

    for (int i = 0; i<num; i++) {
        a[i] = arc4random()%1000;
    }
    
    for (int i = 0; i<num; i++) {
        // j是从后往前循环
        for (int j = num-1; j>i; j--) {
            // 比较相邻元素大小
            if (a[j-1] > a[j] ) {
                int temp = a[j-1];
                a[j-1] = a[j];
                a[j] = temp;
            }
        }
        
    }
    
    for (int i = 0; i<num; i++) {
        printf("%d -> ",a[i]);
    }
    printf("\n 排序完成\n");
    
}

选择排序法, 时间复杂度O(n^2), 每次从第i个元素之后选出最小值, 然后最小值与a[i]进行交换.

- (void)sortAction {
    //选择排序,找到第i个后续元素中的最小值,然后最小值与i进行交换
    int num = 200;
    int a[num];

    for (int i = 0; i<num; i++) {
        a[i] = arc4random()%1000;
    }
    
    /*
     每次子循环把i之后的最小值找出来放到了i的位置,写法上看着更舒服,不如下面直观好理解
     for(int i=0;i<num;i++){

         for(int j=i;j<num;j++){

             if(a[i]>a[j]){
                 int temp = a[i];
                 a[i]=a[j];
                 a[j]=temp;
             }

         }

     }

     */
    
    for (int i = 0; i<num; i++) {
        
        // 找到i之后的最小值
        int minIndex = i;
        for (int j = i; j<num; j++) {
            
            if (a[minIndex] > a[j]) {
                minIndex = j;
            }
        }
        // 交换最小值和i
        if (i!=minIndex) {
            int temp = a[i];
            a[i] = a[minIndex];
            a[minIndex] = temp;
        }
        
        
    }
    

    for (int i = 0; i<num; i++) {
        printf("%d -> ",a[i]);
    }
    printf("\n 排序完成\n");
  
}

直接插入排序, 时间复杂度O(n^2), 假设前i个元素已经排好序了, 对于第i+1个元素,

如果a[i]<=a[i+1], 正是期望的结果, 不做任何处理;

如果a[i]>a[i+1], 从前i个元素中找一个合适的位置插入a[i+1]; 

- (void)sortAction {
    /*直接插入排序,假设前i个元素已经是排好序了,然后处理第i+1个元素,
     如果a[i]<=a[i+1], 不做任何处理;
     如果a[i]>a[i+1], 在前i个元素中找到一个合适的位置插入此元素
     */
    int num = 500;
    int a[num];

    for (int i = 0; i<num; i++) {
        a[i] = arc4random()%(num*10);
    }
    
    for (int i = 0; i<num-1; i++) {
        
        // a[i]<=a[i+1],不做处理
        // a[i]>a[i+1],在前i中找合适的位置插入
        if (a[i]>a[i+1]) {
            
            // 保存第i+1个值
            int temp = a[i+1];
            // 记录要插入的下标,最后一个大于a[i+1]的元素
            int index = i;
            // 元素后移,找到第一个小于a[i+1]的值下标,
            // 比如1,7,9,5,要处理5的时候,变成1,7,7,9,然后把5放到第一个7的位置
            for (int j=i; j>=0; j--) {
                if (a[j]<temp) {
                    break;
                }
                a[j+1] = a[j];
                index = j;

            }
            a[index] = temp;
            
        }
        
    }
    
    for (int i = 0; i<num; i++) {
        printf("%d -> ",a[i]);
    }
    printf("排序完成\n");
    
}

三者的时间复杂度都是O(n^2), 但是在实际应用中差别却很大. 在同样对50000个无序数字 进行10次排序,差别能有1-3倍.

细心的你是不是看到了希尔排序, 希尔排序是对直接插入排序的改进,  第一批突破了O(N^2)的算法, 值得单独拎出来一篇文章. 先看懂熟悉了插入排序, 在看希尔排序.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值