首页 > 其他分享 >分治思想排序(快速排序、归并排序)

分治思想排序(快速排序、归并排序)

时间:2024-04-07 18:30:32浏览次数:21  
标签:sort 归并 递归 int 分治 问题 排序

分治:分而治之,即把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并

优点:

  1. 降低时间复杂度:分治法可以将大问题分解为小问题,通过解决小问题来有效解决原问题,从而降低算法的时间复杂度
  2. 简单易懂:分治算法的思路通常比较直观,编写代码时难度较低
  3. 并行处理:由于分解得到的子问题之间是相互独立的,可以同时进行解决,提高了解决问题的效率
  4. 容易确定运行时间:分治算法的运行时间通常可以通过分析子问题的数量和每个子问题的复杂度来确定

缺点:

  1. 空间需求大:分治法需要额外的空间来存储子问题的解,可能会导致空间复杂度增加
  2. 递归开销:分治算法通常采用递归方式实现,这会增加函数调用的开销,尤其是在问题规模较大时,可能会导致系统资源的大量消耗,严重时甚至可能导致程序崩溃
  3. 分解和合并的复杂性:虽然子问题的解可以通过合并得到原问题的解,但如果分解和合并的过程过于复杂,可能会使得分解和合并所花费的时间超出暴力解法

1、快速排序

排序一次将数据分割成独立的两部分,其中一份中的所有数据都比另外一份的所有数据都要小,然后对这两部分再次进行该排序,整个排序过程可以使用递归进行来达到整个数据成为有序序列

步骤:

  1. 确定分界数据
  2. 划分、调整区间
  3. 递归划分后的区间
void quick_sort(int q[], int l, int r){
    //递归终止条件
    if (l >= r) return;
    
    int i = l - 1, j = r + 1, x = q[(l + r)/2];
    
    while (i < j){
        do i ++ ; while (q[i] < x);
        do j -- ; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    //递归处理
    quick_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

2、归并排序

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并

步骤:

  1. 确定分界点
  2. 递归排序
  3. 归并,合二为一
void merge_sort(int q[], int l, int r){
    //递归终止条件
    if (l >= r) return;
    //找到分界点
    int mid = l + r >> 1;
    //递归进入更小区间
    merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
    //划分为两个区间进行处理
    int k = 0, i = l, j = mid + 1;
    while (i <= mid && j <= r){
        if (q[i] <= q[j]){
            tmp[k ++ ] = q[i ++ ];
        }else{
            tmp[k ++ ] = q[j ++ ];
        } 
    }
    while (i <= mid){
        tmp[k ++ ] = q[i ++ ];
    }
    while (j <= r) {
        tmp[k ++ ] = q[j ++ ];
    }
    for (i = l, j = 0; i <= r; i ++, j ++ ){
        q[i] = tmp[j];
    }
}

标签:sort,归并,递归,int,分治,问题,排序
From: https://blog.csdn.net/Thewei666/article/details/137469894

相关文章

  • 排序算法——快速排序
    问题描述 现有一组数据:23,45,18,11,13,79,72,25,3,17,请使用快速排序算法将它们按照从小到大的顺序排列。算法思想(1)在无序数据中选一个基准数(通常为数据第一个);(2)将数据中小于基准数的数据移到基准数左边,大于基准数的移到右边;(3)对于基准数左、右两边的数据,不断重复以上两个......
  • Stream流sorted的多级排序问题(巨坑)
    https://blog.csdn.net/qq_28165595/article/details/131152763 前言之前在给一个List集合中对象进行多属性排序,比如先根据对象中的A属性正序排序,若两个对象的A属性值相同,再根据对象的B属性进行正序排序。这种排序在实际开发中比较常见,但是这里面有个坑。举个例子先初始化一个......
  • 自定义排序
    问题:按照A列的排序依据进行排序函数公式:=SORTBY(C2:D8,MATCH(C2:C8,A2:A8,))自定义序列排序:设置自定义序列(如需要): 选取A2:A8》文件》选项》自定义序列》导入自定义排序:选取数据》数据》排序》自定义排序……次序设置为自定义序列......
  • 常见的排序算法——插入排序
    本文记述了插入排序的基本思想和一份参考实现代码,并在说明了算法的性能后用实验进行了验证。◆思想将第一个元素之后的所有元素作为待排序范围,将前面的所有元素作为已排序范围。通过一一比较,逐个交换已排序范围内比第二个元素大的所有元素,使第二个元素被插入到了正确的位置。然......
  • MySQL多表联合查询+分组+排序
    DDLCREATETABLE`student`(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'学号',`createDate`datetimeDEFAULTNULL,`userName`varchar(20)DEFAULTNULL,`pwd`varchar(36)DEFAULTNULL,`phone`varchar(11)DEFAULTNULL,`age`tinyint(......
  • 数据结构 第八章(排序算法)【上】
    写在前面:本系列笔记主要以《数据结构(C语言版)》为参考(本章部分图片来源于王道),结合下方视频教程对数据结构的相关知识点进行梳理。所有代码块使用的都是C语言,如有错误欢迎指出。视频链接:第01周a--前言_哔哩哔哩_bilibili基数排序部分的代码参考了一位小伙伴分享的代码,特此说明一......
  • 堆排序算法
    问题描述现有一组数据:23,45,18,11,13,79,72,25,3,17。请使用快速排序算法将它们按照从小到大的顺序排列。算法思想(1)将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;(2)将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;(3)重新调整结构,使其满足堆定义,然后继续......
  • 单链表的冒泡,选择和快速排序
    单链表的冒泡,选择和快速排序选择排序选择排序的原理是在每一趟遍历时找出所有数据中最小或者最大的那一个值,然后放到开头或者末尾,在链表里面也是同样的道理,在下面的代码当中,遍历了一遍链表之后,我们找出了最大的那个值,然后用头插法插入链表的开头,关键的地方是链表不能查找......
  • Python常用算法--排序算法【附源码】
    应用具体python案例方式展示各种排序的要点,特别是希尔排序、插入排序、选择排序、冒泡排序、堆排序、快速排序、归并排序七个具体的排序算法。一、希尔排序:解释:希尔排序(ShellSort)是一种插入排序的改进版本,也被称为缩小增量排序。希尔排序通过比较相距一定间隔的元素,将大间隔......
  • 排序查询
    排序查询语法:select查询列表(III)from表名(I)[where筛选条件](II)orderby排序列表[asc(升序,可省略)/desc(降序)](IV)特点:1、asc升序,可省略,desc降序,如不写默认升序2、orderby子句中支持单个字段、多个字段、表达式、函数、别名3、order......