• Java算法:快速排序


    一、快速排序

            快速排序算法是对冒泡排序算法的一种改进算法,在当前所有内部排序算法中,快速排序算法被认为是最好的排序算法之一。

          基本思想:通过一趟排序将待排记录分隔成独立的左右两部分,左边的子序列中所有数据都比右边子序列中的数据小,然后对左右两个子序列继续进行排序,直到整个序列有序。 

            快速排序使用分而治之 divide and conquer(D&C)法来把一个串(list)分为两个子串(sub-lists)

    二、快速排序步骤

    1. 从数组中按照一定的规则选择一个元素作为基准值
    2. 把基准值与其他元素进行比较,将元素分成两部分,把所有比基准值小的值放在左侧,所有比基准值大的放在右侧。即进行区域划分
    3. 通过递归上述操作,再次将左右两区域进行区域划分,完成排序.

    三、java实现快速排序 

    1. public static void main(String[] args) {
    2. //调用数据
    3. Integer[] datas =getData();
    4. System.out.println("排序前的数组:"+Arrays.toString(datas));
    5. sort(datas, 0, datas.length-1);
    6. System.out.println("排序后的数组:"+ Arrays.toString(datas));
    7. }
    8. /**
    9. * (1) 生成1-100范围的随机数10个
    10. */
    11. private static Integer[] getData() {
    12. Set<Integer> sets = new HashSet<>();
    13. Random random = new Random();
    14. while (true) {
    15. //生成1-100的随机数
    16. int ran = random.nextInt(100) + 1;
    17. //添加
    18. sets.add(ran);
    19. //判断生成10个数据
    20. if (sets.size() >= 10) {
    21. break;
    22. }
    23. }
    24. //Set转换成数组
    25. Integer[] arr = sets.toArray(new Integer[sets.size()]);
    26. return arr;
    27. }
    28. /**
    29. * @param arrs 数组无序
    30. * @param before (子)序列最前面的索引
    31. * @param after (子)序列最后面的索引
    32. */
    33. public static void sort(Integer[] arrs, int before, int after) {
    34. int left = before; //左边
    35. int right = after; //右边
    36. int key = arrs[before]; //基准值
    37. //循环比较
    38. while (right > left) {
    39. //(1)从后往前比较
    40. while (right > left && arrs[right] >= key) //如果没有比关键值小的,比较下一个,直到有比关键值小的交换位置,然后又从前往后比较
    41. right--;
    42. //判断有比关键值小的交换位置
    43. if (arrs[right] <= key) {
    44. int temp = arrs[right];
    45. arrs[right] = arrs[left];
    46. arrs[left] = temp;
    47. }
    48. //(2)从前往后比较
    49. while (right > left && arrs[left] <= key)//如果没有比关键值大的,比较下一个,直到有比关键值大的交换位置
    50. left++;
    51. //判断有比关键值大的交换位置
    52. if (arrs[left] >= key) {
    53. int temp = arrs[left];
    54. arrs[left] = arrs[right];
    55. arrs[right] = temp;
    56. }
    57. }
    58. // 此时第一次循环比较结束,关键值的位置已经确定了。
    59. // 左边的值都比关键值小,右边的值都比关键值大,
    60. // 但是两边的顺序还有可能是不一样的,进行下面的递归调用
    61. //递归关键值左右二边的子序列
    62. if (left > before) {
    63. //递归左边子序列
    64. sort(arrs, before, left - 1);
    65. }
    66. if (right < after) {
    67. //递归右边子序列
    68. sort(arrs, right + 1, after);
    69. }
    70. }
    71. }

    四、性能分析

         优点:效率高,时间复杂度平均为O(nlogn),快速排序是最快的排序算法,耗费的资源少,最佳情况下,空间复杂度为O(logn),每一次都平分数组的情况,代码较为简单。

         缺点:不稳定,初始序列有序或基本有序时,时间复杂度降为O(n^2)。

  • 相关阅读:
    K3S 系列文章-5G IoT 网关设备 POD 访问报错 DNS 'i/o timeout'分析与解决
    【C刷题初阶】刷爆力扣第一弹
    软件开发项目文档系列之九如何撰写测试方案
    PDF标准详解(一)——PDF文档结构
    redis删除缓存
    学生HTML静态网页设计作业成品【汽车商城、汽车租赁、汽车销售】HTML+CSS+JS购物商城
    【网络安全技术】——期末复习(冲刺篇)
    平面口径天线简谈
    oepnpnp - 自己出图做开口扳手
    100天精通Andriod逆向——第4天:各种抓包工具学习
  • 原文地址:https://blog.csdn.net/hlx20080808/article/details/134246369