目录
第十一章 进阶算法之“搜索排序”
11.1 排序和搜索简介
可以在这个visualgo官网网站查看排序算法的动画演示。
11.2 JavaScript 实现:冒泡排序
代码实现:
Array.prototype.bubbleSort = function () {
for (var i= 0;i<this.length-1;i+=1){
for(var j=0;j<this.length-1-i;j+=1){
if(this[j]>this[j+1]){
var temp = this[j];
this[j]=this[j+1];
this[j+1]=temp;
}
}
}
}
var arr = [5,4,3,2,1];
arr.bubbleSort();
代码解读:
同下
11.3 JavaScript 实现:选择排序
代码实现:
Array.prototype.selectionSort = function () {
// 进行n-1次循环
for (var i = 0; i < this.length - 1; i += 1) {
// 进行第一轮循环,找到最小值,把所有0改为i则是从下标i开始下一轮循环
var indexMin = i;
for (var j = i; j < this.length; j += 1) {
if (this[j] < this[this[indexMin]]) {
indexMin = j;
}
}
if(indexMin !==i){
// 实现最小值和第一个值进行交换
var temp = this[i];//声明一个临时变量
this[i] = this[indexMin];
this[indexMin] = temp;
}
}
代码解读:
Array.prototype.selectionSort = function () {
// 进行第一轮循环,找到最小值
var indexMin = 0;
for (var j = 0; j < this.length; j += 1){
if (this[j] < this[this[indexMin]]) {
indexMin = j;
}
}
// 实现最小值和第一个值进行交换
var temp = this[0];
this[0] = this[indexMin];
this[indexMin] = temp;
}
Array.prototype.selectionSort = function () {
// 进行n-1次循环
for (var i = 0; i < this.length - 1; i += 1) {
// 进行第一轮循环,找到最小值
var indexMin = 0;
for (var j = 0; j < this.length; j += 1) {
if (this[j] < this[this[indexMin]]) {
indexMin = j;
}
}
// 实现最小值和第一个值进行交换
var temp = this[0];//声明一个临时变量
this[0] = this[indexMin];
this[indexMin] = temp;
}
}
11.4 JavaScript 实现:插入排序
代码实现:
Array.prototype.insertionSort = function () {
for (var i = 1; i < this.length; i += 1) {
var temp = this[i];
var j = i;
while (j > 0) {
if (this[j - 1] > temp) {
this[j] = this[j - 1];
} else {
break;
}
j -= 1;
}
this[j] = temp;
}
}
var arr = [5, 3, 2, 1, 4];
arr.insertionSort();
11.5 JavaScript 实现:归并排序
代码实现:
Array.prototype.mergeSort = function () {
var rec = (arr) => {
if (Array.length === 1) {
if (arr.length == 1) {
return arr; }
var mid = Math.floor(arr.length / 2);
var left = arr.slice(0, mid);
var right = arr.slice(mid, arr.length);
var orderLeft = rec(left);
var orderRight = rec(right);
var res = [];
while (orderLeft.length || orderRight.length) {
if (orderLeft.length && orderRight.length) {
res.push(orderLeft[0] < orderRight[0] ? orderLeft.shift() : orderRight.shift());
} else if (orderLeft.length) {
res.push(orderLeft.shift());
} else if (orderRight.length) {
res.push(orderRight.shift());
}
}
return res;
var res = rec(this);
res.forEach((n, i) => {
this[i] = n; });
};
var arr = [5, 4, 3, 2, 1];
arr.mergeSort();
}
}
11.6 JavaScript 实现:快速排序
Array.prototype.quickSort = function(){
// 写一个递归
var rec = (arr)=>{
if (arr.lenght === 1) {
return arr;}//递归的停止条件,当数组的长度为1时,输出数组
var left = [];//基准数左边的那个数
var right = [];//基准数右边的那个数
var mid = arr[0];//基准数
for(let i = 1; i < arr.lenght; i +=1){
//循环动作
if(arr[i]<mid){
//当前数小于基准数时,则推入左边数组
left.push(arr[i]);
}else{
//当前数大于基准数时,则推入右边数组
right.push(arr[i]);
}
}
return [...rec(left), mid, ...rec(right)];//返回左边排列好的数组,基准数,返回右边排列好的数组
};
var res = rec(this);
res.forEach((n, i) => {
this[i] = n});
};
var arr = [2, 4, 5, 3, 1];
arr.quickSort();
11.7 JavaScript 实现:顺序排序
// 顺序搜索
Array.prototype.sequentialSearch = function (item) {
// 遍历数组
for (let i = 0; i < this.length; i += 1) {
if (this[i] === item) {
//如果当前值是目标值则返回数组下标
return i;
}
}
return -1;//没有找到目标值则返回-1
};
const res = [1, 2, 3, 4, 5].sequentialSearch(4);调用函数,找到目标值为4的值
11.8 JavaScript 实现:二分搜索
// 二分搜索,前提是数组已经是排好序的了,以下代码是在已经排好序的情况下进行二分搜索
Array.prototype.binarySearch = function (item) {
let low = 0;//最小下标值
let high = this.length - 1;//最大下标值
while (low <= high) {
const mid = Math.floor((low + high) / 2);//取数组中间长度值,floor可以把小数点后的数给去掉取整
const element = this[mid];//获取数组中间值
if (element < item) {
//如果数组中间值小于目标值,则在大的那一半数组里搜索
low = mid + 1;
} else if (element > item) {
//如果数组中间值大于目标值,则在小的那一半数组里搜索
high = mid - 1;
} else {
//如果数组中间值等于目标值,则返回当前值的数组下标
return mid;
}
}
return -1;//没有找到目标值则返回-1
};
const res = [1, 2, 3, 4, 5].binarySearch(4);//调用函数,找到目标值为4的值
11.9 LeetCode: 21. 合并两个有序链表
var mergeTwoLists=function(l1,l2){
const res=new ListNode(0);//新建一个新的链表
let p=res;//新建一个指针,指向res的头部,需要把新链表的指针,不停地指向最后一个结点
let p1=l1;//新建一个指针,指向l1的头部
let p2=l2;//新建一个指针,指向l2的头部
while(p1&&p2){
//在p1且p2有值的情况下进行以下代码
if(p1.val<p2.val){
//如果p1的值小于p2的值
p.next=p1;//把p1赋值给p的下一个结点,也就是新链表的最后一个结点
p1=p1.next;//更新p1指针,把p1往后移一位
}else{
//如果p1的值大于p2的值
p.next=p2;//把p2赋值给p的下一个结点,也就是新链表的最后一个结点
p2=p2.next;//更新p2指针,把p2往后移一位
}
p=p.next;//把p指针不断后移,保证p永远指向链表的最后一个结点
}
// 另一种情况,只在p1或者p2有值的情况下
if(p1){
//在p1有值的情况下
p.next=p1;//因为p1是一个有序链表,直接把后面的值接到p的最后一个结点上
}
if(p2){
//p2有值的情况下
p.next=p2;//因为p2是一个有序链表,直接把后面的值接到p的最后一个结点上
}
return res.next;//因为res是指向链表头部的上一个结点,所以返回它的下一个结点
};
11.10 LeetCode: 374. 猜数字大小
11.11 搜索排序总结