算法:交换排序

1.交换排序

1.1 基本思想

  • 两两比较,如果发生逆序则交换,知道所有记录都排好序为止。

1.2 常见的交换排序

  • 冒泡排序
  • 快速排序

2.冒泡排序

2.1 基本思想

  • 每趟不断将记录两两比较,并按“前小后大”规则交换

2.2 冒泡排序排序过程(升序)

  • 初始:21、25、49、25*、16、8 n=6
    • ·······
    • 第二趟排序:
      • 排序后结果:21、25、16、8 、25* 、49 n=6
    • 第一趟排序:
      • 第一次排序:判断 21、25是否逆序,不是 则21、25、49、25*、16、8 n=6
      • 第二次排序:判断 25、49是否逆序,不是 则21、25、49、25*、16、8 n=6
      • 第三次排序:判断 49、25*是否逆序,是 则21、25、25*、49、16、8 n=6
      • 第四次排序:判断 49、16是否逆序,是 则21、25、25*、16、49、8 n=6
      • 第五次排序:判断 49、8是否逆序,是 则21、25、25*、16、8 、49 n=6

2.3 算法描述

void bubble_sort(Sqlist &L){
    int m,i,j;RedType x;
    for(m=1;m<=n-1;m++){
        for(j=1;j<=n-m;j++){
            if(L.r[j].key < L.r[j+1].key){
                x=L.r[j];
                L.r[j]=L.r[j+1];
                L.r[j+1]=x;            
            }        
        }    
    }
}

public static void bubbleSort(int[] arr){
    int n = arr.length-1;
    for(int i=n;i>=0;--i){
        for(int j=0;j<i;j++){
            if(arr[j] >arr[j+1]){
                int temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
}

2.4 特点

  • 优点:每趟结束时,不仅能挤出一个最大值到后面,还能同时部分理顺其他元素;
    • 如何提高效率?
      • 一旦某一趟比较时不出现记录交换,说明已经排好序了,就可以结束本算法。

2.5 冒泡排序算法分析

  • 时间复杂度
    • 算法评价
      • 最好情况下时间复杂度:O(n)
      • 最坏情况下时间复杂度:O(n²)
      • 平均时间复杂度:O(n²)
      • 空间复杂度:O(1)
      • 冒泡排序是稳定排序。
    • 最好情况(正序)
      • 比较次数:n-1
      • 移动次数:0
    • 最坏情况(逆序)
      • 比较次数:(n-1)*n/2
      • 移动次数:3(n-1)*n/2

3.快速排序

3.1 基本思想

  • 任取一个元素为中心(pivot)。
    • 直到每个子表的元素只剩一个。
    • 对各个子表重新选择中心元素并以此规则调整。
    • 所有比它小的元素一律放前,比他大的元素一律放后,形成左右两个子表。

2.2 算法过程

  • 每一趟的子表的形成都是采用从两头向中间交替式逼近法
    • 由于每趟中对各字表的操作都相似,可采用递归算法。

2.3 算法描述

public static void quickSort(int[] arr){
    if(arr.length>0){
        uickSort(arr,0,arr.length-1);
    }
}
private static void uickSort(int[] arr,int low,int high){    
    int pivot,i,j;
    if(low>=high){
        return;
    }

    pivot = arr[low];
    i=low;
    j=high;
    while(i<j){
        while(arr[j] >= pivot && i<j){
            j--;
        }
        while(arr[i] <= pivot && i<j){
            i++;
        }

        if(i<j){
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    arr[low] = arr[i];
    arr[i] = pivot;
    uickSort(arr,low,i-1);
    uickSort(arr,i+1,high);
}

void main(){
    QSort(L,1,L.length);
}
void QSort(Sqlist &L,int low,int high){	//对顺序表L进行快速排序
    if(low<high){				//长度大于1
        povitloc = Partition(L,low,high);	//将L一分为二,povitloc为数轴元素排好序的位置
        QSort(L,low,povitloc-1);		//对低位子表排序
        QSort(L,povitloc+1,high);		//对高位子表排序
    }
}
int Partition(Sqlist &L,int low,int high){
    L.r[0] = L.r[low];povitkey = L.r[low].key;
    while(low<high){
        while(low<high && L.r[high].key >= povitkey)high--;
        L.r[low]=L.r[high];
        while(low<high && L.r[low].key <= povitkey)low++;    
        L.r[high]=L.r[low];
    }
    L.r[low] = L.r[0];
    return low
}

2.4 快速排序算法分析

  • 时间复杂度
    • 自然性
      • 快速排序不适于对原本有序或者基本有序的记录序列进行排序。
    • 稳定性
      • 快速排序是一种不稳定的排序方法。
        • 例如:49,38,49*,20,97,76
        • 进行一次排序后结果为:20,38,49*,49,97,76
    • 空间复杂度
      • 快速排序不是原地排序
      • 由于程序中使用了递归,需要递归调用栈的支持,而栈的长度取决于递归调用的深度。
        • 平均情况下:O(log(n))
        • 最坏情况下:O(n);
    • 可以证明,平均计算时间是O(nlog2(n))。
      • Qsort():O(log2(n));
      • Partition():O(n);
    • 实验结果表明,就平均计算时间而言,快速排序时我们所讨论的所有内排序方法最好的一个
  • 快速排序效率影响分析
    • 划分元素的选取是影响时间性能的关键
    • 输入的次序越乱,所选划分元素值的随机性越好,排序速度越快,快速排序不是自然性排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值