三大基础排序(冒泡排序,选择排序,插入排序)思想

版权声明:@ly https://blog.csdn.net/lytwy123/article/details/83831067

1.冒泡排序


1-1 思想:

冒泡排序思想:从数组的下标为0的元素开始,首先将下标为0的下标与数组下标为1的元素比较,如果数组下标1
的元素更小,交换,接着比较下标1与下标2的元素,如果下标2较小则交换,反之接着将下标2与下标3比较。。。
以此类推,经过n-1趟排序就可以得到结果 。
比如5,4,3,2,1
第一趟:5,4比较交换。交换后:4,5,3,2,1
5,3比较交换。交换后:4,3,5,2,1
5,2比较交换。交换后:4,3,2,5,1
5,1比较交换。交换后:4,3,2,1,5
剩下的以此类推
如果是五个数只要四趟循环就可以排好,n个数据只要(n-1)趟排序
每一趟排序需要比较的次数,五个数的话第一趟比较4次
第二趟比较3次,因为第一趟已经把最大的元素找到了
所以只要在剩下4个元素中比较3次即可
剩下的以此类推。
时间复杂度:O(N^2) 。


1-2源代码:

/*
冒泡排序思想:从数组的下标为0的元素开始,首先将下标为0的下标与数组下标为1的元素比较,如果数组下标1
的元素更小,交换,接着比较下标1与下标2的元素,如果下标2较小则交换,反之接着将下标2与下标3比较。。。
以此类推,经过n-1趟排序就可以得到结果 
时间复杂度:O(N^2) 
*/

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int nums[101];

void BubbleSort(int *a,int n)
{
    for(int i = 0;i<n;i++){
        for(int j = 0;j<n-i-1;j++){
            if(a[j]>a[j+1])
            {
                swap(a[j],a[j+1]);
            }
        }
    }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>nums[i];
    BubbleSort(nums,n);
    for(int i = 0;i<n;i++)
    cout<<nums[i]<<" ";
    return 0;
}

2.选择排序


2-1思想:

选择排序思想:每次排序将数组中最小的元素放到未排序的第一个
如 3 2 0 5 1
先以数组首元素为参考值,然后依次与后面的元素比较,有小的将其交换
第二步,从数组的第二个元素为参考值,然后依次与剩下的元素比较,有小的将其交换 。
比如5,4,3,2,1
第一趟:5为参考值,然后与4比较交换,交换后:4,5,3,2,1
然后以4为参考值,与3比较交换,交换后:3,5,4,2,1
然后以3为参考值,与2比较交换,交换后:2,5,4,3,1
然后以2为参考值,与1比较交换,交换后:1,5,4,3,2
第二趟以此类推
一共进行n-1趟排序,每一趟排序进行n-i-1次排序
后面依次类推 。
时间复杂度为O(N^2) 。


2-2源代码:

/*
选择排序思想:每次排序将数组中最小的元素放到未排序的第一个
如 3 2 0 5 1
先以数组首元素为参考值,然后依次与后面的元素比较,有小的将其交换
第二步,从数组的第二个元素为参考值,然后依次与剩下的元素比较,有小的将其交换 
后面依次类推 
时间复杂度为O(N^2) 

*/ 

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

int a[1000];

void SelectionSort(int *a,int n)
{
     for(int i = 0;i<n;i++)
     {
         for(int j = i+1;j<n;j++)
         {
             if(a[j]<a[i])
             swap(a[j],a[i]);
         }
     }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>a[i];
    SelectionSort(a,n);
    for(int i = 0;i<n;i++)
    cout<<a[i]<<" ";
    return 0;
}

3.插入排序


3-1思想:

插入排序思想:插入排序就是先将数组首元素不动,从数组的第一个开始与前一个数比较,如果小于当前元素则
交换,反之不作操作,做完这一步操作以后,我们暂且认为数组的0,1位置排好序,然后用下标为2的元素与前一
个元素(下标1的元素)比较,如果较小则交换,进而再与下标为1的元素的前一个比较,如果较小则在交换。这
就类似于我们在0,1排好序了而需要将2对应的元素插入到原来排好序的0,1中
比如5,4,3,2,1。
第一趟排序:5与4比较交换变成4,5
第二趟排序:因为4,5排序好了,先将3与5比较交换,再将3与4比较交换。
以此类推一共需要进行n-1趟排序
以此类推
时间复杂度:与数组的数据状况有关系
假设是有序的1,2,3,4,5只做比较而不用交换,此时时间复杂度O(N)最好情况
假设是无序的5,4,3,2,1每次都要交换,此时时间复杂度为O(N^2)最坏情况
实际上,插入排序是O(N^2)


3-2源代码:

/*
插入排序思想:插入排序就是先将数组首元素不动,从数组的第一个开始与前一个数比较,如果小于当前元素则
交换,反之不作操作,做完这一步操作以后,我们暂且认为数组的0,1位置排好序,然后用下标为2的元素与前一
个元素(下标1的元素)比较,如果较小则交换,进而再与下标为1的元素的前一个比较,如果较小则在交换。这
就类似于我们在0,1排好序了而需要将2对应的元素插入到原来排好序的0,1中 
以此类推 
时间复杂度:与数组的数据状况有关系
假设是有序的1,2,3,4,5只做比较而不用交换,此时时间复杂度O(N)最好情况 
假设是无序的5,4,3,2,1每次都要交换,此时时间复杂度为O(N^2)最坏情况 
实际上,插入排序是O(N^2) 
*/

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

int a[1000];

void InsertSort(int *a,int n)
{
    for(int i = 0;i<n-1;i++)    //实际交换只有n-2次 
    {
        for(int j = i+1;j>=0;j--)
        {
            if(a[j]<a[j-1])
            swap(a[j-1],a[j]);
        }
    }
}

int main()
{
    int n;
    cout<<"input n:"<<endl;
    cin>>n;
    for(int i = 0;i<n;i++)
    cin>>a[i];
    InsertSort(a,n);
    for(int i = 0;i<n;i++)
    cout<<a[i]<<" ";
    return 0;
}

4.总结

现在,这三大基础算法,冒泡与选择已经基本不用了,因为效率低,但是插入排序还会继续用。
因为冒泡与选择不管数组的数据是否有序,它都需要进行规定操作时间复杂度为O(N^2)。
而插入排序在数组有序的情况下根本不用交换时间复杂度为O(N),还是相当可观的。
在使用基础算法排序时,尽可能使用插入排序。

可以关注一下自建Blog:http://47.107.118.184

猜你喜欢

转载自blog.csdn.net/lytwy123/article/details/83831067