选择排序
function selectionSort(arr){
// minIndex 用来寻找最小元素,
let minIndex , temp;
for(let i = 0 ; i<arr.length-1;i++){
minIndex = i // 设置当前下标为最小元素
//j 是从当前 i 往后遍历一遍剩下的元素,所以 j 的总长度取 arr 的长度
//搞清楚双重for循环中i与j的关系便比较好理解此解法
for(let j=i+1;j<arr.length;j++){
if(arr[j]<arr[minIndex]){
minIndex = j
}
}
//找到最小元素后与当前元素的置换位置
temp = arr[i]
arr[i] = arr[minIndex]
arr[minIndex] = temp
}
return arr
}
插入排序
function insertionSort(arr){
const len = arr.length
let preIndex,current
for(let i = 1; i< len ;i++){
preIndex = i - 1;
current = arr[i];
while(preIndex >= 0 && arr[preIndex] > current){
arr[preIndex + 1] = arr[preIndex];
preIndex--;
}
arr[preIndex + 1]= current
}
return arr
}
分析过程:
当输入数组为[3,2,1]时,
i= 1,preIndex = 0 ,current = 2, 数组变更为 [2,3,1] preIndex = -1 ;
i = 2,preindex = 1,current = 1, 数组变更为 [2,3,3] preIndex = 0
满足while 循环 继续 数组变更为 [2,2,3] 后preIndex = -1
不满足while循环 进行current赋值 [1,2,3]
冒泡排序
function sort(arr){
let len = arr.length
for(let i = 0 ; i<len-1;i++){
for(let j = 0 ; j<len-1-i;j++){
if(arr[j]>arr[j+1]){
let temp = arr[j+1]
arr[j+1] = arr[j]
arr[j] = temp
}
}
}
return arr
}
冒泡排序是进行两两比对,不断的对比将较大的元素不断的往后置换
所以此处注意到j层的循环 取的长度是len-1-i
如果取len-1 最终答案也是一样的,但是多了很多不必要的已确立位置元素的遍历
希尔排序
希尔排序主要是以间隔来进行插入排序 间隔到最后为1时 再次进行插入排序时的数组已经有一定的有序化程度了,所以效率上对于插入排序有一定的提高
function shellSort(arr){
let len = arr.length,gap = Math.floor(len/2);
// gap 即为间隔
for(gap;gap>0;gap = Math.floor(gap/2)){
for(let i = gap; i < len; i++){
let j = i;
let current = arr[i];
while(j-gap >=0 && current <arr[j-gap]){
arr[j] = arr[j-gap];
j = j-gap
}
arr[j] = current
}
}
return arr
}
快速排序
主要是以分组与递归来实现
function quickSort(arr,L,R){
let len = arr.length;
let partitionIndex //基准点下标
let left = typeof L === 'number' ? L : 0
let right = typeof R === 'number' ? R : len-1
if( left < right ){
partitionIndex = partition(arr, left, right)
quickSort(arr, left , partitionIndex-1)
quickSort(arr, partitionIndex+1 , right)
}
return arr
}
// 获取基准点
function partition(arr, left, right){
let pivot = left; //选取以left为基准点
let index = pivot+1;
for(let i = index; i <= right ; i++){
// 遍历的元素与基准点相比较
if(arr[i] < arr[pivot]){
swap(arr, i, index)
index ++;
}
}
swap(arr,pivot,index-1)
return index - 1
}
// 置换元素位置
function swap(arr,i,j){
console.log(i,j,'i,j')
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
链表
两个有序链表的合并
prehead 为头指针 是为了最后return的时候完整的链表进行输出
prev 是处理过程中用来衔接的指针
由于两个链表已经是有序的,只需按顺序一对一的比较即可
function mergeTwoLists(l1, l2) {
const prehead = new ListNode(-1);
let prev = prehead;
while(l1 !== null && l2 !== null){
if(l1.val <= l2.val){
prev.next = l1
l1 = l1.next
}else{
prev.next = l2
l2 = l2.next
}
prev = prev.next
}
prev.next = l1 === null ? l2 : l1 // 由于while的循环条件是&& 所以肯定有一个链表存在还未合并的元素 所以需改变指向指向还存在元素的链表即可
return prehead.next;
}