排序算法

选择排序—简单选择排序(Simple Selection Sort)

(我的最爱,最先想到的排序算法)

基本思想:
在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

我的code:

a[]:待排序的数组
n:   数组的大小
n = sizeof(a)/sizeof(a[0]);
void SimSelectSort(int a[],int n)
{

    int tmp=0;
    //   i  0~8  9次排序完成
    //  i值控制着 排序的趟  数
    for(int i=0;i<n-1;i++)
    {
        //j 1~9 
        //j 控制要比较数值的序号
        for(int j=i+1;j< n ;j++)
        {
            //每一次排序后,最小的上浮。
            if(a[i]>a[j])
            {
                tmp =a[j];
                a[j] = a[i];
                a[i] = tmp;
            }
        }
        cout << a[i] << "  ";
    }

}

该算法的时间复杂度为:O(n^2)

交换排序—冒泡排序(Bubble Sort)

(容易跟选择排序搞混)

基本思想:
在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

我的code:

void BubbleSort(int a[],int n)
{
    int tmp=0;
    //   1-9
    for(int i=1;i<n;i++)
    {
        //j 0----(n-i-1)
        //初始值:0  ---  8控制趟数
        for(int j=0;j< n-i ;j++)
        {
            //每一次排序后,小的上浮,大的下沉。
            //每一趟走完,最大值沉底
            if(a[j]>a[j+1])
            {
                tmp =a[j+1];
                a[j+1] = a[j];
                a[j] = tmp;
            }


            //下面两个if只是为了突出显示每一趟的最大值
            //输出最后的大值
            if( j == n-i-1)
            {
                cout << a[j+1] << "  " ;
            }
            //输出最小值,第一个元素
            if(j==0 && (n-i-1) == 0)
            {
                cout << a[j] << " " ;
            }
        }

    }
}

该算法的时间复杂度为:O(n^2)

对冒泡算法的改进
1.设置一标志性变量exchange,用于标志某一趟排序过程中是否有数据交换,如果进行某一趟排序时并没有进行数据交换,则说明数据已经按要求排列好,可立即结束排序,避免不必要的比较过程。

插入排序—直接插入排序(Straight Insertion Sort)

基本思想:
将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。
要点:设立哨兵,作为临时存储和判断数组边界之用

算法的稳定性
如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

我的code:

void SimInsertSort(int a[],int n)
{
    for(int i=1;i<n;i++)
    {
        if(a[i] < a[i-1])  //第i个元素小于前一个元素,直接插入
        {
            int j = i-1;
            int x =a[i];   //复制为哨兵
            a[i] = a[i-1] ; //先后移动一个元素
            while( x < a[j] )
            {
                a[j+1] = a[j];
                j--;            //元素后移
            }
            a[j+1] = x;           //插入到正确的位置
        }

    }

}

该算法的时间复杂度为:O(n^2),由此分出的排序算法有二分插入排序,2-路插入排序。

快速排序–(Quick Sort)

基本思想:
(一般取第一个元素)
1)选择一个基准元素,通常选择第一个元素或者最后一个元素,

2)通过一趟排序讲待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小。另一部分记录的 元素值比基准值大。

3)此时基准元素在其排好序后的正确位置

4)然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。

我的Code:

//交换函数
void swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
//打印输出函数
void print(int a[], int n)
{
    for(int j=0;j<n;j++)
    {
        cout << a[j] << "  " ;
    }
    cout << endl;
}
//以基准元素为标杆的分组函数
int partition(int a[],int low,int high)
{
    int pivotKey = a[low];//基准元素
    while(low < high)
    {
        //从high所指向的位置向前搜索,至多到low+1
        //比基准小的元素交换到低端
        while(low < high && a[high] >= pivotKey ) 
        {
            //比基准大 ,不交换,继续往前
            --high;
        }
        //后半部分比基准小的,要交换
        swap(&a[low],&a[high]);
        print(a,10);

        while(low < high && a[low] <= pivotKey)
        {
            ++low;
        }
        swap(&a[low],&a[high]);
        print(a,10);
    }
    print(a,10);
    cout << "一趟分表完成" <<endl;
    return low;

}

//递归调用partition函数,实现快速排序
void quickSort(int a[],int low,int high)
{
    if(low < high)
    {
        int pivotLoc = partition(a,low,high); //通过pivotLoc值,将表一分为二
        quickSort( a, low, pivotLoc - 1);        //递归对低子表递归排序
        quickSort( a, pivotLoc + 1, high);        //递归对高子表递归排序
    }
}

给定输入:int int_arr[] = { 7,6,3,1,2,9,11,10,8,5 };
程序输出结果:
这里写图片描述

算法性能分析:
**时间复杂度:O(nlog2^n)
空间复杂度:O(nlog2^n)
算法是不稳定的;**

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值