数据结构与算法之排序算法(二):交换排序

交换排序可以分为:冒泡排序和快速排序。其中快速排序是对冒泡排序的改进
1.冒泡排序

原理:比较临近的两个数字,按照从小到大的顺序进行交换,这样一趟过去后,最大(最小)的数字被交换到了最后一位,然后再从头开始进行两两比较交换,直到倒数第i位时结束。

代码实现:
for(int i=0;i<a.length-1;i++){
    for(int j=i + 1; j<a.length;j++){
        if(a[j] < a[j-1]){
            a[j] = a[j] ^ a[j-1];
            a[j-1] = a[j] ^ a[j-1];
            a[j] = a[j] ^ a[j-1];
        }
    }
}

分析:稳定,空间复杂度O(1),时间复杂度【最佳、最差、平均都是O(n*n)】。

改进:如果当前顺序已经正确,就没有必要再冒泡了。可以定义一个标志变量来标志是否当前顺序已正确。
代码实现:
for(int i=0;i<a.length-1;i++){
    bool swap = false; //定义一个标志变量swap
    for(int j=1;j<a.length-i;j++){
        if(a[j] < a[j-1]){
            a[j] = a[j] ^ a[j-1];
            a[j-1] = a[j] ^ a[j-1];
            a[j] = a[j] ^ a[j-1];
            swap = true;
        }
    }
    if(!swap){return;}
}

分析:稳定,空间复杂度O(1),时间复杂度[最佳为O(n)、最差、平均都是O(n*n)]。

2.快速排序(冒泡排序的改进)

原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另一部分的数据小。然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行。

实现思路:

  1. 以第一个关键字k1为控制字(枢轴),将[k1,k2,....kn]分成两个子区。使左区所有关键字都小于等于控制字,右区所有关键字都大于等于控制字,最后控制字居两个子区中间适当的位置。
  2. 将左区和右区分别进行递归处理。

代码实现:

public static void main(String[] args) {
        int[] arr = new int[]{50,10,90,20,40,60,80,70};
        quickSort(arr,0,arr.length-1);
        print(arr);
    }
private static void print(int[] arr) {
        for (int i : arr){
            System.out.println(i + " ");
        }
    }
private static void quickSort(int[] arr, int left, int right) {
        //定义关键字pivot
        int pivot = 0;
        if (left < right){
           //将序列分成两个子区,算出关键字值
            pivot = partition(arr,left,right);
            //递归左子区
            quickSort(arr,left,pivot - 1);
            //递归右子区
            quickSort(arr,pivot + 1,right);
        }
}
private static int partition(int[] arr, int left, int right) {
       //将序列第一个元素作为关键字,缓存起来
        int pivotKey = arr[left];
        //循环条件,两个指针left,right,分别指向序列的两端,直到两个指针重合
        while(left < right){
        //将序列最右端的值与关键字比较,如果大于,则应放在关键字右边,right减1(向左移动一个),直到不满足条件为止
            while(left < right && arr[right] >= pivotKey){
                right--;
            }
            //当right遇到第一个小于关键字或者两个指针重合时,将该值赋给左指针指向的位置,left向右移动。right停止移动
            arr[left++] = arr[right];
            //此时移动left
            while(left < right && arr[left] <= pivotKey){
                left++;
            }
            //当left遇到第一个大于关键字或者两个指针重合时,将该值赋给右指针指向的位置,lright向左移动。left停止移动
            arr[right--] = arr[left];
        }
        arr[left] = pivotKey;//将关键字赋值给left
        return left;//返回关键字所在位置
    }
}

分析:算法不稳定,空间代价【最坏O(n)、最好和平均O(logn)】,时间代价【最坏O(n*n)、最好和平均O(nlogn)】.
时间: 2025-01-17 18:36:24

数据结构与算法之排序算法(二):交换排序的相关文章

在Object-C中学习数据结构与算法之排序算法

笔者在学习数据结构与算法时,尝试着将排序算法以动画的形式呈现出来更加方便理解记忆,本文配合Demo 在Object-C中学习数据结构与算法之排序算法阅读更佳. 目录 选择排序 冒泡排序 插入排序 快速排序 双路快速排序 三路快速排序 堆排序 总结与收获 参考与阅读 选择排序 选择排序是一种简单直观的排序算法,无论什么数据进去都是 O(n2) 的时间复杂度.所以用到它的时候,数据规模越小越好.唯一的好处可能就是不占用额外的内存空间了吧. 1.算法步骤 首先在未排序序列中找到最小(大)元素,存放到排

算法学习-排序算法

数据结构-算法复杂度 时间复杂度 事件频度 一个算法花费的时间与算法种语句的执行次数成正比,哪个算法种语句执行次数多,它花费时间就多. 一个算法中的语句执行次数称为语句频度或时间频度.记为T(n) eg:计算1-100的和 方法一:for循环 T(n) = n + 1 方法二:直接计算 T(n) = 1 时间复杂度 一般情况下,算法中的基本操作语句的重复执行次数时问题规模n的某个函数,用T(n)表示,若有某个辅助函数f(n),使得当n趋近于无穷大时,T(n) / f(n) 的极限值为不等于0的常

【C/C++学院】0907-象棋五子棋代码分析/寻找算法以及排序算法

象棋五子棋代码分析 编译代码报错: 错误 1 error MSB8031: Building an MFC project for a non-Unicode character set is deprecated. You must change the project property to Unicode or download an additional library. See http://go.microsoft.com/fwlink/p/?LinkId=286820 for mo

STL算法之排序算法

STL排序算法通常复杂度坏于线性,且必须要random-access Iterators. 所以,forward_list, list, associative and unordered contains 不提供随机访问迭代器,这些容器不能用排序算法. 但是,forward_list,list提供了成员函数sort,associative contains 自动排序,unordered contains不能排序. 通常,排序元素一次要比保持元素有序要更快.STL提供了不同的排序算法,根据需求选

c/c++ 通用的(泛型)算法 之 只读算法,写算法,排序算法

通用的(泛型)算法 之 只读算法,写算法,排序算法 只读算法: 函数名 功能描述 accumulate 求容器里元素的和 equal 比较2个容器里的元素 写算法 函数名 功能描述 fill 用给定值,覆盖给定的范围的元素 fill_n 用给定值,覆盖给定开始位置后的,n个元素变 back_inserter 在容器末尾插入元素 copy 把容器1指定范围里的值拷贝给容器2,并返回指向容器2最后一个元素的下个元素 replace 用某个值替换掉给定范围的某个值 replace_copy 用某个值替

算法之排序算法总结

算法之排序算法总结 | Carrie博客 全部 全部 博客 友链 关于 ps:这里的排序都是从小到大进行排列. 冒泡排序 算法思想:从第一个数开始,将两个相邻的数进行比较,如果前一个数大于后一个数,则互换位置,否则保持不变.这样比较一趟,可以把最大的数放在末尾(根据循环的趟数决定).依次循环,直到排序完成. 时间复杂度:O(n^2) 大专栏  算法之排序算法总结li>空间复杂度:O(1) 选择排序 算法思想:从待排序的数字中找出最小的数,放在排序数字的最开始,之后依次在未排序的数字中选出最小的数

数据结构常见的八大排序算法(详细整理)

https://www.jianshu.com/p/7d037c332a9d?utm_campaign=hugo&utm_medium=reader_share&utm_content=note&utm_source=weixin-friends 八大排序,三大查找是<数据结构>当中非常基础的知识点,在这里为了复习顺带总结了一下常见的八种排序算法.常见的八大排序算法,他们之间关系如下: 排序算法.png 他们的性能比较: 性能比较.png 下面,利用Python分别将他

javascript数据结构与算法--高级排序算法

高级排序算法是处理大型数据集的最高效排序算法,它是处理的数据集可以达到上百万个元素,而不仅仅是几百个或者几千个.现在我们来学习下2种高级排序算法---- 希尔排序和快速排序. 一:希尔排序: 希尔排序的核心理念是:首先比较距离较远的元素,而非相邻的元素. 基本原理:通过定义一个间隔序列来表示在排序过程中进行比较的元素之间有多远的间隔. 下面我们来看看数组[0,9,1,8,7,6,2,3,5,4] 来使用希尔排序的原理:如下图: 代码分析如下: 1. 执行 "间隔序列=3的步骤" A.

数据结构——常见的十种排序算法

一.常见的十种排序算法: 冒泡排序.选择排序.插入排序.归并排序.快速排序.希尔排序.堆排序.计数排序.桶排序.基数排序 1.[知识框架] 补充:内部排序:整个排序过程完全在内存中进行. 外部排序:由于待排序记录数据量太大,内存无法容纳全部数据,需要借助外部存储. 二.排序方法 ?插入排序 1.算法思想 从待排序的第二个元素开始,向下扫描列表,比较这个目标值target与arr[i-1].arr[i-2]的大小,依次类推.如果target的值小于或等于每一个元素值,那么每个元素都会向右滑动一个位

数据结构和算法--6排序算法

1.排序的分类 1) 内部排序:指将需要处理的所有数据都加载到内部存储器中进行排序 2) 外部排序:无法全部加载到内存中,需要借助外部存储进行 3)图示: 2.算法的时间复杂度 1)  度量一个程序(算法)执行时间的两种方法 A.事后统计的方法 问题:a.需要实际运行该程序.b.时间也依赖于计算机的硬件,软件等环境因素.所以要在同一台计算机的相同状态下运行,才能比较哪个算法速度更快 B.事前估算的方法 通过分分析某个算法的时间复杂度来判断哪个算法更优 2)  时间频度 A. 基本介绍 一个算法花