排序总结大全

冒泡排序 (Bubble Sort)

1.基本思想 :
从无序序列头部开始,进行两两比较,根据大小交换位置,知道最>后将大(小)的数据元素交换到无需队列的队尾,从而成为有序列表的一部分;下一次继续这个过程,直到所有数据元素都排好序

2.运行过程
冒泡排序算法的运作如下:
(1)比较相邻的元素。比如第一个比第二个大(小),就交换它们两个。
(2)对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大(小)的数。
(3)针对所有的元素重复以上的步骤,除了最后已选出的元素(有序)。
(4)持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需>要比较,则序列最终有序。

一趟排序:

下标 0 1 2 3 4
value 5 3 2 4 1
下标 0 1 2 3 4
value 5 3 2 1 4
下标 0 1 2 3 4
value 5 3 1 2 4
下标 0 1 2 3 4
value 5 1 3 2 4
下标 0 1 2 3 4
value 1 5 3 2 4

3.算法实现( 核心代码 )

void BubbleSort(int a[],int n)
{
   
    for(int i = n-1; i; i--)  // n- 1轮冒泡
        for(int j = 0; j < i; j++) //每轮进行 i 次比较
            if(a[j] > a[j+1])  //逆序
                swap(a[j], a[j+1]);  //交换
}
public int[] bubbleSort(int[] A, int n) {
   
    for (int i = 0; i < n - 1; i++) {
   
        for (int j = 0; j < n - i - 1; j++) {
   
            if (A[j] > A[j + 1]) {
   
                int temp = A[j];
                A[j] = A[j + 1];
                A[j + 1] = temp;
            }
        }
    }
    return A;
}

冒泡排序法中的交互次数又称为反序数或逆序数,体现数据的错乱程度。

bool ok = true;
int i=0,num=0;  // i:表示未排序部分的开头元素,从数组开头向末尾移动
while(ok){
   
    ok = false;
    for(int j = N - 1; j >= i + 1; j--){
    // j:表示对未排序部分中的相邻元素两两比较,
                                       //从 a[] 末尾 N - 1 开始,减少到 i + 1 结束
        if(a[j] < a[j-1]){
     //与上述代码相反,这个将最小值从后面往前移动,固定最小值
            swap(a[j], a[j-1]);
            num++;  //记录交换次数
            ok=true;
        }
    }
}

冒泡排序仅对数组中的相邻元素进行比较和交换,因此键相同的元素不会改变顺序,因此是稳定的排序算法。但是如果将 A [ j ] < A [ j − 1 ] A[j] < A[j-1] A[j]<A[j1] 改成 A [ j ] A[j] A[j] ≤ \leq A [ j − 1 ] A[j-1] A[j1],算法失去稳定性。假设数据量是 N N N,对未排序部分的相邻元素进行 ( N − 1 ) + ( N − 2 ) + ⋯ + 1 = ( N 2 − N ) 2 (N-1) + (N-2) + \cdots +1 = \frac{(N^2-N)}{2} (N1)+(N2)++1=2(N2N),所有时间复杂度最坏情况是 ( N 2 ) (N^2) (N2)

选择排序 (Selection Sort)

1.基本思想
对比数组中前一个元素跟后一个元素的大小,如果后面的元素比前面的元素小(大)则用一个变量k来记住他的位置,接着第二次比较,前面“后一个元素”现变成了“前一个元素”,继续跟他的“后一个元素”进行比较,如果后面的元素比他要小(大)则用变量k记住它在数组中的位置(下标),等到循环结束的时候,我们应该找到了最小(大)的那个数的下标了,然后进行判断,如果这个元素的下标不是第一个元素的下标,就让第一个元素跟他交换一下值,这样就找到整个数组中最小(大)的数了。然后找到数组中第二小(大)的数,让他跟数组中第二个元素交换一下值,以此类推。
2.运行过程
(1)定义一个变量tmp记录待替换元素位置。
(2)比较待替换元素与当前元素的位置;若待替换元素大(小),则将tmp下标移到当前元素
(3)待替换元素与其后所有元素比较结束之后,交换待替换元素和tmp下标所记录的元素位置
(4)针对每一个元素重复以上操作,直到所有元素都有序。

下标 0 1 2 3
value 3H 5S 3D 1S
下标 0 1 2 3
value 1S 5S 3D 3H
下标 0 1 2 3
value 1S 3D 5S 3H
下标 0 1 2 3
value 1S 3D 3H 5S

3.算法实现(核心代码)

void selectsort(int a[],int n)
{
   
    int pos,sw=0;   //pos存未排序部分最小值的下标
    for(int i = 0; i < n-1; i++)
    {
   
        pos=i;
        for(int j = i + 1; j < N; j++)
            if(a[j] < a[pos]) pos = j;
        if(i != pos) sw++,swap(a[i],a[pos])
    }
    return sw;   //返回的交换次数
}
public static int[] selectionSort(int[] A) {
   
    for (int i = 0; i < A.length - 1; ++i) {
   
        int tmp = i;
        for (int j = i + 1; j < A.length; ++j) {
   
            if (A[tmp] > A[j])
            tmp = j;
        }
        if (tmp != i) {
   
            int temp = A[tmp];
            A[tmp] = A[i];
            A[i] = temp;
        }
    }
    return A;
}

选择排序会直接交换两个不相邻的元素,所以属于不稳定的排序算法。假设数据是 N N N,选择排序算法需要进行 ( N − 1 ) + ( N − 2 ) + ⋯ + 1 = ( N 2 − N ) 2 (N-1) + (N-2) + \cdots + 1 = \frac{(N^2-N)}{2} (N1)+(N2)++1=2(N2N) 次运算,用于搜索未排序部分的最小值,时间复杂度 O ( N 2 ) O(N^2) O(N2)

判断稳定性,时间复杂度 O ( N 4 ) O(N^4) O(N4)

bool Check(int in[],int out[],int N)
{
   
    for(int i = 0; i < N; i++)
        for(int j = i + 1; j < N; j++)
            for(int a = 0; a < N; a++)
                for(int b = a + 1; b < N; b++)
                    if(in[i] == out[j] && in[i] == out[b] && in[j] == out[a])
                        return false;
    return true;
}

插入排序(Insertion Sort)

1.基本思想
每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的元素中适当位置上,直到全部插入完为止。

2.运行过程
(1)从第一个元素开始,该元素可以认为已经被排序。
(2)取出下一个元素,在已经排序的元素序列中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸愉信奥

谢谢亲的支持,我会继续努力啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值