内容简介:思路/原理:比较相邻的两个元素,如果前一个比后一个大,则交换位置,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。就好像一串气泡一样,最终从小到大或从大到小依次排下来。
冒泡排序
思路/原理:比较相邻的两个元素,如果前一个比后一个大,则交换位置,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。就好像一串气泡一样,最终从小到大或从大到小依次排下来。
function bubbleSort(arr) {
var len = arr.length;
// i表示第几趟排序
for(var i = 0; i < len - 1; i++) {
// j表示交换次数
for(var j = 0; j < len - 1 - i; j++) {
if(arr[j] > arr[j + 1]) {
// var temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
}
}
}
return arr;
}
console.log(bubbleSort([3, 1, 8, 10, 5]));复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n)
空间复杂度: O(1)
稳定性: 稳定
由于冒泡 排序 只在相邻元素大小不符合要求时才调换他们的位置,它并不改变相同元素之间的相对顺序,因此它是稳定的排序算法。
复杂性: 简单
选择排序
思路/原理: 每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕。
function selectSort(arr) {
var len = arr.length;
// 控制位置
for(var i = 0; i < len - 1; i++) {
// 假如这个是最小的
var min = i;
// 与后面的数字进行比较 寻找最小值的索引
for(var j = i + 1; j < len; j++) {
if(arr[j] < arr[min]) {
min = j;
}
}
// 如果当前的值的索引和最小值的索引不相等 交换位置
if(i !== min) {
[arr[i], arr[min]] = [arr[min], arr[i]];
}
}
return arr;
}复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n²)
空间复杂度: O(1)
稳定性: 不稳定
Tips: 选择排序每次交换的元素都有可能不是相邻的 因此它有可能打破原来值为相同的元素之间的顺序 比如数组[2,2,1,3] 正向排序时 第一个数字2将与数字1交换 那么两个数字2之间的顺序将和原来的顺序不一致 虽然它们的值相同 但它们相对的顺序却发生了变化 我们将这种现象称作 不稳定性 .
选择排序的简单和直观名副其实 这也造就了它"出了名的慢性子" 无论是哪种情况 哪怕原数组已排序完成 它也将花费将近n²/2次遍历来确认一遍 即便是这样 它的排序结果也还是不稳定的 唯一值得高兴的是 它并不耗费额外的内存空间
插入排序
思路/原理: 将排序分为排序与未排序,将未排序的数依次向排序数进行比较。
function insertSort(arr) {
var len = arr.length;
for (var i = 1; i < len; i++) {
var temp = arr[i]; // 要插入的元素
// 与前面的排序好的数组进行比较
var j = i - 1;
while(j >= 0 && temp < arr[j]) {
// 如果当前元素小于他们 则他们往后运动 并交换当前元素和他们的位置 否则不动
arr[j + 1] = arr[j];
j --;
}
arr[j + 1] = temp;
}
return arr
}
console.log(insertSort([2, 1, 4, 8, 3])); 复制代码
时间复杂度: 平均情况O(n²) 最坏情况O(n²) 最好情况O(n)
空间复杂度: O(1)
稳定性: 稳定
Tips: 由于直接插入排序每次只移动一个元素的位置 并不会改变值相同的元素之间的排序 因此它是一种稳定排序
归并排序
思路/原理: 归并排序建立在归并操作之上 它采取分而治之的思想 将数组拆分为两个子数组 分别排序 最后才将两个子数组合并 拆分的两个子数组 再继续递归拆分为更小的子数组 进而分别排序 直到数组长度为1 直接返回该数组为止
// 采用分而治之的思想 把数组以递归的方式分为左右相等的两个数组
function mergeSort(arr) {
var len = arr.length;
// 递归出口
if(len < 2) {
return arr;
}
var mid = parseInt(len / 2),
left = arr.slice(0, mid),
right = arr.slice(mid);
return merge(mergeSort(left), mergeSort(right));
}
// 把两个数组进行排序
function merge(left, right) {
var res = [];
while(left.length && right.length) {
if(left[0] < right[0]) {
res.push(left.shift());
}else {
res.push(right.shift());
}
}
// 把剩余的数组连接
while(left.length) {
res.push(left.shift());
}
while(right.length) {
res.push(right.shift());
}
return res;
}复制代码
时间复杂度: 平均情况O(n log n) 最坏情况O(n log n) 最好情况O(n log n)
空间复杂度: O(n)
稳定性: 稳定
Tips: 由于直接插入排序每次只移动一个元素的位置 并不会改变值相同的元素之间的排序 因此它是一种稳定排序
你的点赞是我持续输出的动力 希望能帮助到大家 互相学习 有任何问题下面留言 一定回复
未完待续。。。。。。。。。。。。。。。。。。。。。。。。。
以上所述就是小编给大家介绍的《应届生必须掌握的十大排序算法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 算法之常见排序算法-冒泡排序、归并排序、快速排序
- 排序算法之冒泡排序改进算法
- 快速排序算法,C语言快速排序算法深入剖析
- 排序算法下——桶排序、计数排序和基数排序
- 数据结构和算法面试题系列—排序算法之快速排序
- 数据结构和算法面试题系列—排序算法之基础排序
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Reversing
艾拉姆(Eilam,E.) / 韩琪、杨艳、王玉英、李娜 / 电子工业出版社 / 2007-9 / 79.00元
本书描述的是在逆向与反逆向之间展开的一场旷日持久的拉锯战。作者Eldad Eilam以一个解说人的身份为我们详尽地评述了双方使用的每一招每一式的优点与不足。 书中包含的主要内容有:操作系统的逆向工程;.NET平台上的逆向工程;逆向未公开的文件格式和网络协议;逆向工程的合法性问题;拷贝保护和数字版权管理技术的逆向工程;防止别人对你的代码实施逆向工程的各种技术;恶意程序的逆向工程;反编译器的基本......一起来看看 《Reversing》 这本书的介绍吧!