插入排序、选择排序、冒泡排序、希尔排序

版权声明:小牛牛的奋斗 https://blog.csdn.net/qq_43590403/article/details/89047234

引入概念排序稳定性:输入数据的顺序,排序后不能改变。例如,1,2,3,3,5.排序完若第一个3和第二个3互换,则为不稳定。
1.插入排序(稳定)

解释:像打扑克时整理牌时一样,遇到小牌就插在前面比他大的前面,而后面的牌顺次后移;直到处理完最后一张牌。
优点:比冒泡排序只能处理相邻数据更为灵活,适用于数据在一定距离之间排序较为整齐,可以极大提高效率。

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

void insertSort(int a[],int n)//插入排序
{
    int i,j,v;
    for(i=1;i<n;i++)
    {
        v=a[i];
        j=i-1;
        while(j>=0&&a[j]>v)
        {
            a[j+1]=a[j--];
        }
        a[j+1]=v;
    }
}
void printArr(int a[],int n)//遍历数组
{
    for(int i=0;i<n;i++)
    {
        if(i==0)
            cout<<a[i];
        else
            cout<<" "<<a[i];
    }
    cout<<endl;
}

int main()
{
    int a[100],n;

    cin>>n;

    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    insertSort(a,n);
    printArr(a,n);

    return 0;
}

2.冒泡排序(稳定)
解释:从后往前,比较相邻的元素,若不符合条件,则调用swap函数交换数据。外循环一次,将最小的放到第一位置,重复到最后一个元素归位。
优点:代码实现较为简单,但处理数据不灵活,只能处理相邻元素。

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

void bubbleSort(int a[],int n)//冒泡排序
{
    int i,j;
    for(i=0;i<n;i++)
        for(j=n-1;j>=i+1;j--)
        {
            if(a[j]<a[j-1])
                swap(a[j],a[j-1]);
        }
}
void printArr(int a[],int n)//遍历数组
{
    for(int i=0;i<n;i++)
    {
        if(i==0)
            cout<<a[i];
        else
            cout<<" "<<a[i];
    }
    cout<<endl;
}

int main()
{
    int a[100],n;

    cin>>n;

    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    bubbleSort(a,n);
    printArr(a,n);

    return 0;
}


3.选择排序(不稳定)

解释:找到一个最小的就替换第一个元素,第二次找第一个之后的最小值,替换第二个元素。。。。

注意:外层循环为0~n-1。
优点:放眼全局,冒泡为局部。由于选择替换的大幅度性,会造成排序的不稳定

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

void selectSort(int a[],int n)//选择排序
{

    int i,j,mini;
    for(i=0;i<n-1;i++)
    {
        mini=i;//存储一次循环最小值的下标
        for(j=i;j<n;j++)
            if(a[j]<a[mini])
                mini=j;
        swap(a[i],a[mini]);
    }
}

void printArr(int a[],int n)//遍历数组
{
    for(int i=0;i<n;i++)
    {
        if(i==0)
            cout<<a[i];
        else
            cout<<" "<<a[i];
    }
    cout<<endl;
}

int main()
{
    int a[100],n;

    cin>>n;

    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    selectSort(a,n);
    printArr(a,n);

    return 0;
}

4.希尔排序(稳定)

解释:其实就是将插入排序进行了升级,将间隔由普通插入函数的1,变为了动态的3*n+1,经过一次外循环,他就会整齐一点,直到执行到g=1时,基本已经排的差不多了,so,此排序具有插入排序的优点又解决了数列不太整齐时普通插入复杂度高的问题。每外循环一次,下一次的内循环就会少很多步骤。是集中了许多优点的排序算法。他的写法就是插入排序和g的取值函数的集合。

缺点:相较于前三种,这个排序写起来略有复杂。

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> G;
int a[10000000];

void insertSort(int a[],int n,int g)//插入排序
{
    for(int i=g;i<n;i++)//与普通插入排序一样,只是起点为g.
    {
        int v=a[i];
        int j=i-g;
        while(j>=0&&a[j]>v)
        {
            a[j+g]=a[j];
            j-=g;
        }
        a[j+g]=v;
    }
}

void sellSort(int a[],int n)//希尔排序,G数组存储间隔数,如:1,4,13,3*n+1....
{
    int h=1;
    while(h)
    {
        if(h>n)
            break;
        G.push_back(h);
        h=3*h+1;
    }
    for(int i=G.size()-1;i>=0;i--)
    {
        insertSort(a,n,G[i]);//调用插入排序执行间隔为3*n-1,13,4,1的排序
    }
}

void printArr(int a[],int n)//遍历数组
{
    for(int i=0;i<n;i++)
    {
        if(i==0)
            cout<<a[i];
        else
            cout<<" "<<a[i];
    }
    cout<<endl;
}

int main()
{
    int n;

    cin>>n;

    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    //insertSort(a,n);
    sellSort(a,n);
    printArr(a,n);

    return 0;
}


猜你喜欢

转载自blog.csdn.net/qq_43590403/article/details/89047234