博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据结构与算法-学习笔记(八)
阅读量:5953 次
发布时间:2019-06-19

本文共 2426 字,大约阅读时间需要 8 分钟。

归并排序

思路:将要排序的数组从中间分成两部分,分别排序,再将排序好的两部分合并。

这里用到了分治思想:分而治之,讲一个大问题分解成若干个小问题来解决。很明显这里需要用到递归这种编程方式。

function mergeSort(array, region1, region2) {    var tempArray = [];    var i = region1[0];    var j = region2[0];    for (; i <= region1[1]; i++) {        for (; j <= region2[1]; j++) {            if (array[i] > array[j]) {                tempArray.push(array[j]);            } else {                break;            }        }         tempArray.push(array[i]);    }        for (; j <= region2[1]; j++) {        tempArray.push(array[j]);    }        var n = 0;    for (let k = region1[0]; k <= region2[1]; k++) {        array[k] = tempArray[n++];    }        return [region1[0], region2[1]];    }function divide(array, start, end) {    if (start >= end) return [start, end];    var mid = Math.floor((end+start)/2);    return mergeSort(array, divide(array, start, mid),divide(array, mid+1, end));     }复制代码

分析:

  1. 稳定的排序;

  2. 根据递推代码求时间复杂度的方法,分析?代码时间复杂度:归并排序的执行效率与数据有序度无关,所有时间复杂度O(nlogn);

  3. 每次合并时,会临时申请一个最大不超过n的内存空间,合并完成释放。而空间复杂度是指算法运行时需要的额外空间,每次执行时函数都仅仅申请了一块内存空间,但并没有累积。因此空间复杂度O(n),不是原地排序,这也是归并排序不如快速排序应用广泛的原因;

快速排序

思路: 同样采用分治思想。 从数组中选一个位置的数据,小于它的放左边,大于它的放右边。之后再分别对左右两边再次进行同样操作以此类推。直到间距缩小到1,说明数据都有序了。其实就是每次通过分区的方式找到一个元素在有序后的数组中的位置。

总结就是:

  1. 对整个数组分区;
  2. 对左边区域分区;
  3. 对右边区域分区。
// 如果pivot==end则只需从一头开始查找了function quickSort(array, start, end) {     if (start >= end) return;        var pivot = divide(array, start, end);         quickSort(array, start, pivot-1);    quickSort(array, pivot+1,end);    }function divide(array, start, end) {    var pivot = end;    // i代表小于pivot的区域边界    var j = 0;    var i = 0;    while (i <= pivot) {        if (array[j] <= array[pivot]) { // 因为此时插入操作不要求保证顺序,用交换就行            if (array[i] != array[j]) {                var temp = array[i];                array[i] = array[j];                array[j] = temp;            }            i++;        }        j++;        if (j >= pivot) break;    }             // 把pivot插入到小于区域的末尾    temp = array[i];    array[i] = array[pivot];    array[pivot] = temp;    pivot = i;        return pivot;    }复制代码

对数组进行分区操作中,为了进行原地排序,空间复杂度为O(1),又尽可能不进行移动,采用了类似插入排序的方式,同时对数组的插入操作采用交换的方式。

而这种交换操作就会造成排序算法的不稳定。

时间复杂度:平均时间复杂度O(nlogn);最坏是O(n2);

归并排序和快速排序的区别

可以发现归并是先处理子问题,然后再合并。而快速则是先对大区域分区,在对子区域分区处理。

快速排序和归并排序的思想应用

除了对无序数组进行排序外,还可以解决如:求无序数组中第K大元素,这样的问题。 快速排序每次分区都会找到pivot元素排序的位置,因此可以每次分区后比较K和pivot的位置大小,进行更加细化的查找。时间复杂度= n+n/2+n/4+n/8+...+1 = O(n);

转载于:https://juejin.im/post/5be14c3df265da6151143650

你可能感兴趣的文章
并查集hdu1232
查看>>
Mysql 监视工具
查看>>
从前后端分离到GraphQL,携程如何用Node实现?\n
查看>>
Linux Namespace系列(09):利用Namespace创建一个简单可用的容器
查看>>
博客搬家了
查看>>
Python中使用ElementTree解析xml
查看>>
jquery 操作iframe、frameset
查看>>
解决vim中不能使用小键盘
查看>>
jenkins权限管理,实现不同用户组显示对应视图views中不同的jobs
查看>>
我的友情链接
查看>>
CentOS定时同步系统时间
查看>>
批量删除用户--Shell脚本
查看>>
如何辨别android开发包的安全性
查看>>
Eclipse Java @Override 报错
查看>>
知道双字节码, 如何获取汉字 - 回复 "pinezhou" 的问题
查看>>
linux中cacti和nagios整合
查看>>
Parallels Desktop12推出 新增Parallels Toolbox
查看>>
Python高效编程技巧
查看>>
Kafka服务端脚本详解(1)一topics
查看>>
js中var self=this的解释
查看>>