最全排序复习资料

一、冒泡排序

原理:依次比较相邻的两个数,将较小的数放在前面,较大的数放在后面

举例:[9,1,34,61,89,36,52]

  第一趟

1.        [1|,9,34,61,89,36,52]   (比较1和9,确定1的位置)

2.        [1,9|,34,61,89,36,52] (比较9和34,确定9的位置)

3.        [1,9,34|,61,89,36,52]  (比较34和61,确定34的位置)

4.        [1,9,34,61|,89,36,52]  (比较61和89,确定61的位置)

5.        [1,9,34,61,36|,89,52]  (比较89和36,确定36的位置)

6.        [1,9,34,61,36,52|,89]  (比较89和52,确定52的位置)

最终确定最大值89

  第二趟

1.        [1|,9,34,61,36,52,89]    (比较1和9,确定1的位置)

2.        [1,9|,34,61,36,52,89] (比较9和34,确定9的位置)

3.        [1,9,34|,61,36,52,89]   (比较34和61,确定34的位置)

4.        [1,9,34,36|,61,52,89]  (比较61和36,确定36的位置)

5.        [1,9,34,36,52|,61,89]  (比较52和61,确定52的位置)

最终确定第二大的值61

......以此类推

  第六趟

1.        [1,9,34,36,52,61,89]  (比较1和9,确定1的位置)

最终确定第六大的值9

则最小值不用比较,直接为1

  推广:假设一共有n个数字,要比较n-1趟,每趟要比较n-i次,一共要比较n*(n-1)/2次

  时间复杂度为:O(n2)   具有稳定性

  代码实现:

/*冒泡排序*/

#include <stdio.h>

void main()

{

    int a[100], i, j, k, t, n;

    printf("Input n:\n");

    scanf("%d", &n);

    printf("Input nums:\n");

    for (i = 1; i <= n; i++)

        scanf("%d", &a[i]);

    printf("\n");

    for (j = 1; j <= n - 1; j++)

    {

        for (i = 1; i <= n - j; i++)

        {

            if (a[i] > a[i + 1])

            {

                t = a[i];

                a[i] = a[i + 1];

                a[i + 1] = t;

            }

            for (k = 1; k <= n; k++)

            {

                printf("%d ", a[k]);

            }

            printf("\n");

        }

    }

    printf("The sorted numbers:\n");

    for (i = 1; i <= n; i++)

        printf("%d ", a[i]);

}

二、选择排序

原理:每一轮选择最小项与第一位交换

(假设a[1]是最小项min,比较所有数据得出最小项a[x],若1!=x,则交换)

举例:[9,1,34,61,89,36,52]

1.        [1|,9,34,61,89,36,52]   (最小值1与9交换,确定1的位置)

2.        [1,9|,34,61,89,36,52] (最小值9不换,确定9的位置)

3.        [1,9,34|,61,89,36,52]  (最小值34不换,确定34的位置)

4.        [1,9,34,36|,89,61,52]  (最小值36与61交换,确定36的位置)

5.        [1,9,34,36,52|,61,89]  (最小值52与89交换,确定52的位置)

6.        [1,9,34,36,52,61|,89]  (最小值61不换,确定61的位置)

  推广:假设一共有n个数字,要比较n-1趟,每趟要比较n-i次确定最小值

  时间复杂度为:O(n2)    不具有稳定性

代码实现:

#include <stdio.h>

void main()

{

    int a[100], i, j, min, t,k, n;

    printf("Input n:\n");

    scanf("%d", &n);

    for (i = 1; i <= n; i++)

    {

        scanf("%d", &a[i]);

    }

    printf("Input nums:\n");

    for (i = 1; i <= n - 1; i++)

    {

        k = i;

        for (j = i + 1; j <= n; j++) //选择

            if (a[j] < a[k])

                k = j;

        if (i != k) //交换

        {

            t = a[i];

            a[i] = a[k];

            a[k] = t;

        }

    }

    printf("The sorted numbers:\n");

    for (i = 1; i <= n; i++)

        printf("%d ", a[i]);

}

三、快速排序

原理:把小于基准元素的值放在左边,大于基准元素的值放在右边

(假定左边第一个为基准元素,则L指向左一,R指向右一,从右边的R开始向中间移动,若R指向元素大于基准元素,则不移动元素,R向前一位;若该元素小于基准元素,则将其元素移至左一L的指向处,开始移动左边L,若元素小于基准则前移L,反之将元素移至右边R处,以此类推,直至L、R重合,则将基准元素移至此处。确定基准元素后,再同样处理其左边和右边的数,直至全部有序)

举例:[9,1,34,61,89,36,52]

1.       9 [ *  ,1,34,61,89,36,52*]   (以9为基准元素,L指向左空,R指向右52)

          9 [ *  ,1*,34,61,89,36,52] (R从右往左移动,直到R指向1,1<9,将1移至L指向位)

          9 [1*,  *,34,61,89,36,52]  (1<9,L右移,则L、R重合,将9放在此位)

           [1,9,34,61,89,36,52]  

2.          [1,9,34,61,89,36,52]  (1有序,则将9右边数列排序)

        34 [1,9,*  ,61,89,36,52*]  (以34作为基准元素,L指左空,R指右52)

        34 [1,9,* *,61,89,36,52]   (R从右往左移动,直到R与L重合,将34放在此位)

           [1,9,34,61,89,36,52]  (最小值61不换,确定61的位置)

3.     61 [1,9,34,*  ,89,36,52*]  (将61作为基准元素,L指左空,R指右52)

        61 [1,9,34,*  ,89,36,52*]   (52<61,将52移至L处)

        61 [1,9,34,52,*89,36,  *]    (L从左开始移动,89>61,将89移至右R)

        61 [1,9,34,52,*  ,36*,89]  (R开始前移,36<61,将36移至左L)

        61 [1,9,34,52,*36,   *,89]  (L开始前移,直至L、R重合)

           [1,9,34,52,36,61,89]  

4.          [1,9,34,52,36, 61,89]  (89有序,则左边排序)

       52  [1,9,34,*  ,36*, 61,89]  (以52为基准,左L右36R)

        52 [1,9,34,*  ,36*, 61,89]  (36<52,移至左L)

        52 [1,9,34,*36, *, 61,89]  (左L前移,直至L、R重合)

           [1,9,34,36 ,5261,89]  

 

推广:假设一共有n个数字   平均时间复杂度为:O(Nlog2N)   不具有稳定性

代码实现:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值