[题解]《算法零基础100讲》(第33讲) 排序入门 - 冒泡排序

一. 冒泡排序

  冒泡排序的原理就和从水底的冒上来的气泡一样,气泡越大,其排开的水体积就越大,上浮的也就越快,所以一般上面的气泡会比下面的气泡要大(当然气泡上升过程中不断变大是因为水压减小的缘故),而冒泡排序的形式也是差不多的,如果是进行升序排序的话,就是将较大的数据往右边移动,每次循环都会将一个最大的数据排到最右边。

例图:
请添加图片描述
所以经过多轮排序后,整个数组就排成了一个升序的形式。

1.1 源码刨析

#include <stdio.h>

int main(){
    
    
	int nums[] = {
    
     10, 9, 8, 7, 6, 5, 4, 3 ,2, 1, 0 };
	int length = sizeof(nums) / sizeof(nums[0]);

	for (int i = 0; i < length; i++){
    
    
		for (int j = 0; j < length - i - 1; j++){
    
    
			if (nums[j] > nums[j + 1]){
    
    
				int tmp = nums[j];
				nums[j] = nums[j + 1];
				nums[j + 1] = tmp;
			}
			
		}
	}

	for (int i = 0; i < length; i++){
    
    
		printf("%d ", nums[i]);
	}
	printf("\n");
	return 0;
}

在这里插入图片描述

  1. 从下标0开始,对数组进行遍历,相邻两个元素进行比较,如果前面的比后面的大,则交换位置,这样进行一轮后,便将最大的值移动到了最右边。
  2. 经过第一次遍历后,我们还剩下numsSize - 1个元素需要排序,然后对这numsSize - 1个元素进行相同的操作,便将第二大的数字移动到倒数第二个位置
  3. 以此类推,大概经过n^2次的遍历后,得到一个升序的排序。

二. 相关练习

2.1 颜色分类

题目链接:

75. 颜色分类
  

这道题就是让你写一个冒泡排序,所以我们直接用上面的代码即可。

代码如下:

void sortColors(int* nums, int numsSize){
    
    
    for(int i = 0; i < numsSize; i++){
    
    
        for(int j = 0; j < numsSize - i - 1; j++){
    
    
            if(*(nums + j) > *(nums + j + 1)){
    
    
                int tmp = *(nums + j);
                *(nums + j) = *(nums + j + 1);
                *(nums + j + 1) = tmp;
            }
        }
    }
}

在这里插入图片描述

2.2 寻找两个正序数组的中位数

题目链接:

4. 寻找两个正序数组的中位数

分析:

这道题很水说实话,我们直接通过双指针的形式把两个数组合并,最后取中间值即可。

代码如下:

double findMedianSortedArrays(int* nums1, int nums1Size, int* nums2, int nums2Size)
{
    
    
    int* ret = (int*) malloc (sizeof(int) * (nums1Size + nums2Size));
    int retSize = 0;
    int p1 = 0, p2 = 0;
    while(p1 < nums1Size || p2 < nums2Size){
    
    
        if(p1 < nums1Size && p2 < nums2Size){
    
    
            if(nums1[p1] < nums2[p2]){
    
    
                ret[retSize++] = nums1[p1++];
            }
            else{
    
    
                ret[retSize++] = nums2[p2++];
            }
        }
        else if(p1 < nums1Size){
    
    
            ret[retSize++] = nums1[p1++];
        }
        else if(p2 < nums2Size){
    
    
            ret[retSize++] = nums2[p2++];
        }
    }
    if(retSize % 2){
    
    
        return (double)ret[retSize/2];
    }
    return (double)(ret[(retSize-1)/2] + ret[retSize / 2])/2;
}

在这里插入图片描述

2.3 至少是其他数字两倍的最大数

题目链接:
747. 至少是其他数字两倍的最大数

分析:

我们可以定义两个变量max1和max2,然后遍历数组nums,当max1<nums[i]时,令max2 = max1,然后令max1 = nums[i],如果遇到max1 > nums[i] && max2 < nums[i],则令max2 = nums[i]。遍历完数组后我们便可得到前两个大的数字,最后对他们进行比较判断。

代码如下:

int dominantIndex(int* nums, int numsSize){
    
    
    if(numsSize == 1){
    
    
        return 0;
    }
    int x = 0;//存储最大值下标
    int max1 = 0, max2 = 0;
    for(int i = 0; i < numsSize; i++){
    
    
        //找最大值
        if(max1 < nums[i]){
    
    
            max2 = max1;
            max1 = nums[i];
            x = i;
        }//找第二大值
        else if(max2 < nums[i]){
    
    
            max2 = nums[i];
        }
    }
    //比较判断
    if(max2 * 2 <= max1){
    
    
        return x;
    }
    return -1;
}

在这里插入图片描述

三. 推荐专栏

  

《算法零基础100讲》(第33讲) 排序入门 - 冒泡排序

Guess you like

Origin blog.csdn.net/qq_53060585/article/details/121464748