交换排序算法

交换排序算法

一、介绍

1、概念

就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

2、特点

将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

二、常用算法

冒泡排序、快速排序

说明
1. 以下方法最后结果均按照升序排列
2. 用4,2,1,3,7,4,5,8,3,5序列进行测试

1、冒泡排序

(1)基本思想

在n个待排序数组中选取待排序数列中的第一个元素x与第二个元素y进行比较,如果x>y则,将个元素交换位置,否则,选取第二个元素与第三个元素进行比较,以此类推,知道最后两个元素比较完成,则完成一趟排序,此时最后一个元素已经是这个序列中最大的一个元素,第二趟排序时只需在前n-1个元素中进行即可。

(2)代码实现

public void bubbleSort(int[] arr) {
    for (int i = 0; i < arr.length - 1; i++) {
        boolean flag = true; // 设置标记位,记录是否已经完成排序
        for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) { // 相邻位置依次进行比较
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
                flag = false;       //排序还未完成标志位置为false
            }
        }
        print(arr);
        if (flag) {             //当flag为true时表示已经完成排序
            break;
        }
    }
}

(3)运行结果

这里写图片描述

(4)性能

①稳定性:稳定
②时间复杂度:O(n^2)

2、快速排序

(1)基本思想

从待排序数组中选取一个元素作为关键字(这里选取待排序序列中的第一个元素作为关键字),角标为key,分别定义一个指向开始和结尾的指针l和h,如果l所指元素在h所指元素的前面,则从两端到中间将各个元素与关键字进行比较,如果height指向的元素小于等于关键字,则执行h–操作,直到l==h或者h所指元素小于关键字,如果l指向的元素大于等于关键字,则执行l++操作,直到l==h或者l指向的元素大于关键字,如果h找到小于关键字的元素并且l找到大于关键字的元素则将h和l指向的元素交换位置,然后继续从两边向中间进行比较,直到h和l指向同一个元素,将该元素与关键字交换位置,完成一趟排序,此时以关键字为界会将数组划分成两个区域,然后在分别对两段数组进行排序,直到待排序区域中只有一个元素,完成排序。
一句话总结,就是通过交换实现关键字左边的元素不大于关键字,关键字右边的元素不小于关键字。

(2)代码实现

public static void quickSort(int[] arr, int low, int height) {
    int l = low;
    int h = height;
    int key = low;
    while (l < h) {
        while (arr[key] <= arr[h] && l < h) {
            h--;
        }
        while (arr[key] >= arr[l] && l < h) {
            l++;
        }
        // 将小于关键字和大于关键字的元素交换位置
        if (l < h) {
            swap(arr, l, h);
            l++;
            h--;
        }
    }
    // 将关键字换到合适的位置
    swap(arr, key, l);
    print(arr);
    // 以关键字为界限将待排序元素划分成 两个区域分别进行快速排序
    if (low < l - 1)
        quickSort(arr, low, l - 1);
    if (l + 1 < height)
        quickSort(arr, l + 1, height);

}

说明:为什么要先从尾部开始进行循环?
想一想这个例子,将9, 4, 2, 1, 3, 7, 4, 5, 8, 3, 10用快排排序
如果我们首先选9作为关键字并在循环部分用下面的代码结果如何?

while (arr[key] >= arr[l] && l < h) {
    l++;
}
while (arr[key] <= arr[h] && l < h) {
    h--;
}

当l指向10时会因为arr[key] < arr[l]跳出循环,而此时l==h也同时满足,也就是说l和h指向同一个位置,都指向元素10,按照程序的逻辑,此时key指向的元素要和l指向的元素进行交换,也就是10要换到9的左边,交换为10, 4, 2, 1, 3, 7, 4, 5, 8, 3, 9,这就出现了问题,比关键字大的元素到了关键字的左边,而用正确顺序的代码则没有这个问题,所以,我们必须从右边开始,也就是从基数的对面开始。

(3)运行结果

这里写图片描述

(4)性能

①稳定性:不稳定
②时间复杂度:
平均性能O(nlogn) (n倍的log以2为底n的对数)
最坏情况O(n^2)

猜你喜欢

转载自blog.csdn.net/qq_30496695/article/details/73692584
今日推荐