zoukankan      html  css  js  c++  java
  • 【基础算法】冒泡排序+二分查找法

      1、思考题

      (1)有12颗球,1颗是9克,其余的都是10克,怎样在天平上称三次找出9克的那颗质量小的球?

      答:第一次:把12颗球分成两半,一半6颗,在天平上称,取质量小的一边;

        第二次:把6颗球分成两半,一半三颗,也取质量小的一边;

        第三次:取三颗球中任一两颗去称,如果质量相等,那么没有称的那一颗就是质量最小的一颗(9克),如果两颗质量不想等,取质量小的一颗也可以取到。

      (2)有1024个人,有一个人血液有病毒,而999个人没有病毒,化验一个人的血液需要10分钟,怎么用最短的时间找出有血液病毒的那个人?

      答:普通的方法,如果每个人都检查的话,需要话的时间最多需要10000分钟,是需要几天。

               我们这样,1024个人分为两组,每人抽一次血混合,查看有病毒的一组再分成两半测,直到测出为止,这种方法只需要 2x=1024,x=10 ,就只需要10次,100分钟即可

      (3)有1到100的数,随机寻找1到100的数,怎么在最短的时间找到?

      答:把1到一百分成两半,把中间的数和随机数比较,如果随机数大于中间数,选择大于的一半数再分成两半查找,再和随机数比较,不停的分成两半取中间比较值,直到找到为止;如果小于,反之;

      2、二分法查找

      上面的思考题就是运用了二分法查找的原理。

      二分法伪代码: 

                 输入 f(x) 的定义
                 输入 a 和 b 为初始区间
    
                 重复如下:
                 m := (a + b) / 2
                 如果 f(m) * f(a) < 0 则
                 b := m
                 否则
                 a := m
                直至满意为止

      

      3、冒泡排序

      选择排序法

        int a[10] = { 23, 3, 234, 2, 56, 34, 34, 54, 24, 67 };
        //选择排序法
        for (int i = 0; i < 10; i++)
        {
            for (int j = i + 1; j < 10; j++)
            {
                if (a[i] < a[j])
                {
                    int tmp = a[i];
                    a[i] = a[j];
                    a[j] = tmp;
                }
            }
        }

      二分法查找必须针对有序数组,如果不是有序的,我们就要对数组进行排序。冒泡排序算法:

    void  bubble_sort(int arr[], int length)
    {
        for (int i = 0; i < length - 1; i++)
        {
            for (int j = 0; j < length - 1 - i; j++)
            {
                if (arr[j]>arr[j + 1])
                {
                    //交换两个数
                    arr[j] = arr[j] + arr[j + 1];
                    arr[j + 1] = arr[j] - arr[j + 1];
                    arr[j] = arr[j] - arr[j + 1];
                }
            }
        }
    }

      4、二分法查找

    //二分法排序 while循环实现
    int dichotomy1(int arr[], int length, int num)
    {
        int head = 0;
        int foot = length - 1;
        int middle = (head + foot) / 2;
        while (head <= foot)
        {
            if (arr[middle] = num)
            {
                return middle;
               
            }
            else if (arr[middle] < num)
            {
                head = middle-1;
                middle = (head + foot) / 2;
            }
            else if (arr[middle] > num)
            {
                foot = middle+1;
                middle = (head + foot) / 2;
            }
        }
        return -1;
    }
    //二分查找 for循环实现
    int dichotomy2(int arr[], int length, int num)
    {
        for (int head = 0, foot = length - 1, middle = (length-1)/2; head <= foot;middle=(head+foot)/2)
        {
            if (arr[middle] == num)
            {
                return middle;
            }
            else if (arr[middle]>num )
            {
                foot = middle - 1;
            }
            else if (arr[middle]<num)
            {
                head = middle + 1;
                
            }
        }
        return -1;
    }

      5、完整实例

    #include<stdio.h>
    #include<stdlib.h>
    #include<time.h>
    #define N 100
    //二分法排序 while循环实现
    int dichotomy1(int arr[], int length, int num)
    {
        int head = 0;
        int foot = length - 1;
        int middle = (head + foot) / 2;
        while (head <= foot)
        {
            if (arr[middle] = num)
            {
                return middle;
                
            }
            else if (arr[middle] < num)
            {
                head = middle-1;
                middle = (head + foot) / 2;
            }
            else if (arr[middle] > num)
            {
                foot = middle+1;
                middle = (head + foot) / 2;
            }
        }
        return -1;
    }
    //二分查找 for循环实现
    int dichotomy2(int arr[], int length, int num)
    {
        for (int head = 0, foot = length - 1, middle = (length-1)/2; head <= foot;middle=(head+foot)/2)
        {
            if (arr[middle] == num)
            {
                return middle;
            }
            else if (arr[middle]>num )
            {
                foot = middle - 1;
            }
            else if (arr[middle]<num)
            {
                head = middle + 1;
                
            }
        }
        return -1;
    }
    void  bubble_sort(int arr[], int length)
    {
        for (int i = 0; i < length - 1; i++)
        {
            for (int j = 0; j < length - 1 - i; j++)
            {
                if (arr[j]>arr[j + 1])
                {
                    //交换两个数
                    arr[j] = arr[j] + arr[j + 1];
                    arr[j + 1] = arr[j] - arr[j + 1];
                    arr[j] = arr[j] - arr[j + 1];
                }
            }
        }
    }
    void main()
    {
        time_t t;
        srand((unsigned int)time(&t));
        int a[N];
        for (int i = 0; i < N; i++)
        {
            a[i] = rand() % 100;//生成100以内的随机数
            printf("%-2d	", a[i]);
        }
        bubble_sort(a,N);    
        printf("排序后
    ");
        for (int i = 0; i < N; i++)
        {
            printf("%-2d	", a[i]);
        }
        printf("请输入要查找的数
    ");
        int num;
        scanf_s("%d", &num);
        int found = dichotomy2(a,N,num);
        if (found != -1)
        {
            printf("found!a[%d]=%d",found,num);
        }
        else
        {
            printf("not found!");
        }
        system("pause");
    
    }
  • 相关阅读:
    codevs 2632 非常好友
    codevs 1213 解的个数
    codevs 2751 军训分批
    codevs 1519 过路费
    codevs 1503 愚蠢的宠物
    codevs 2639 约会计划
    codevs 3369 膜拜
    codevs 3135 River Hopscotch
    数论模板
    JXOJ 9.7 NOIP 放松模拟赛 总结
  • 原文地址:https://www.cnblogs.com/wangliu/p/4087668.html
Copyright © 2011-2022 走看看