当前位置:首页 > 算法 > 正文内容

【排序】----冒泡排序

亿万年的星光5年前 (2021-01-28)算法3161
1.基本思想

两个数比较大小,较大的数下沉,较小的数冒起来。

2.过程

·每次比较相邻的两个数,如果第二个数小,就交换位置。(升序或降序)

·然后两两比较,一直到比较最后的数据。最终最小(大)数被交换到开始(结束)位置,这样第一个最小(大)数的位置就排好了。

·继续重复上述过程,依次将第2,3…n-1个最小数排好位置。



动图过程:



举例说明:【1 4 3 2】

第一趟排序:

第一次排序:1和4比较,1小于4,不交换位置。 【1 4 3 2】

第二次排序:4和3比较,4大于3,交换位置。 【1 3 4 2】

第三次排序:4和2比较,4大于2,交换位置。 【1 3 2 4】

第二趟排序:

第一次排序:1和3比较,1小于3,不交换位置。 【1 3 2 4】

第二次排序:3和2比较,3大于2,交换位置。 【1 2 3 4】

第三次排序: 3和4比较,3小于4,不交换位置。 【1 2 3 4】

第三趟排序:

第一次排序,1和2比较,1小于2,不交换位置。 【1 2 3 4】

第二次排序,2和3比较,2小于3,不交换位置。 【1 2 3 4】

第三次排序,3和4比较,3小于4,不交换位置。 【1 2 3 4】


2.注意点

在冒泡排序中,两个数比较大小,只需要比较一次就行。

n个数比较大小(选出最大或者最小),比较n-1次就行。


3.参考代码
#include<iostream>
using namespace std;
int main()
{
    int arr[]={12,45,13,88,79,11,52}; //定义数组
    int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
    int length = len-1; //排序总轮数()
    for(int i=0;i<length;i++)
    {
        for(int j=0;j<length-i;j++)
        {
           if (arr[j]>arr[j+1]) //如果前一个数比后一个大
           {
               int temp = arr[j+1];
               arr[j+1] = arr[j];
               arr[j] =temp;
           }
       }
       /*
       for(int i=0;i<length;i++)
            cout<<arr[i]<<" ";
        cout<<endl;
       */
    }
    //输出
    for(int i=0;i<length;i++)
        cout<<arr[i]<<" ";
    return 0;
}



如果需要手动读入数组,那么参考下面这个版本:

#include<iostream>
using namespace std;
int main()
{
     int n,a[100];
	 cin>>n;
	 for(int i=0;i<n;i++){
	 	cin>>arr[i];
	 } 
     for(int i=0;i<n;i++)
     {
         for(int j=0;j<n-1-i;j++)
         {
            if (arr[j]>arr[j+1])  //如果前一个数比后一个大 
            {
                int temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] =temp; 
            } 
        }
        /*
        for(int i=0;i<length;i++)
             cout<<arr[i]<<" "; 
         cout<<endl;
        */
     }
     //输出
     for(int i=0;i<length;i++)
         cout<<arr[i]<<" "; 
     return 0; 
}




4.问题及改进

由程序输出可以看出,在第5次的时候已经排序完了,后面的元素都没有交换过,也就说后面几次排序都是没有意义的。这样就可以改进一下排序算法,设置一个元素位置交换标志记录本次排序是否有位置发生变化,如果没有则认为已经排序完了,不需要再执行了。

#include<iostream>
using namespace std;
int main() {
   int arr[]= {12,45,13,88,79,11,52,66}; //定义数组
   int len =sizeof(arr) / sizeof(arr[0]); //测量数组长度
   int length = len-1; //排序总轮数
   bool flag = true; //标志位,记录每次排序是否有元素位置交换
   for(int i=0; i<length && flag!=false; i++) { //如果上次排序元素位置未改变过,
       flag = false; //每次排序前,标志位复位
       for(int j=0; j<length-i; j++) {
           if (arr[j]>arr[j+1]) { //如果前一个数比后一个大
               flag = true; //发生位置交换,改变标志位
               int temp = arr[j+1];
               arr[j+1] = arr[j];
               arr[j] =temp;
           }
       }
        /*
       for(int i=0;i<length;i++)
            cout<<arr[i]<<" ";
        cout<<endl;
       */
   }
   
  //输出
    for(int i=0;i<length;i++)
        cout<<arr[i]<<" ";
   return 0;
}


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:
    返回列表

    没有更早的文章了...

    下一篇:【排序】----选择排序

    相关文章

    【图论】弗洛伊德算法(Floyd)

    【图论】弗洛伊德算法(Floyd)

    一、算法说明Floyd 算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与 Dijkstra 算法类似。 该算法名称以创始人之一、1978 年图灵奖获得者、斯坦福...

    【DFS】搜索回溯基础

    【DFS】搜索回溯基础

    0.前言       搜索与回溯是计算机解题中常用的算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。...

    【图论】迪杰斯特拉算法

    【图论】迪杰斯特拉算法

    迪杰斯特拉算法是由荷兰计算机科学家艾兹赫尔・迪杰斯特拉于 1956 年提出的单源最短路径算法,用于求解带权有向、 无向图中,从一个源节点到其余所有节点的最短路径问题(要求图中所有边的权值非负)。一、核...

    【算法】动态规划(一)

    1.基本概念在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。因此各个阶段决策的选取不能任意确定,它依赖...

    【贪心】----找零钱问题

    一、找零钱问题例题1:有 1 元,5元,10元,20元,100元,200元的钞票无穷多张。现在使用这些钞票支付X元,最少需要多少张钞票。X = 628最佳支付方法:3张200块的,1张20块的,1张5...

    【算法】动态规划(三)——解题方法与解题思路

    0.前言动态规划最核心的思想就是:拆分子问题,记住过往,减少重复计算。动态规划可以从下面的参考网上的一个例子:A :"1+1+1+1+1+1+1+1 =?"...