WindChaser 2019-06-20
笔试面试如果涉及到数据结构和算法之类的题,貌似都比较喜欢问二叉树,排序算法等,所以整理一下用js写的排序算法
排序算法几个关键点就是时间复杂度、空间复杂度、稳定性,前两者对于数学渣渣的我来说只能尽可能记下来了,判定稳定性主要是看两个相同的元素在排序后和排序前的顺序是否改变,如果改变了就是不稳定
比较相邻的元素,如果第一个数比第二个数大,就交换他们两个,从开始第一对到结尾的最后一对,这样每一轮比较结束都将会把最大的数排在最后,再重复从第一对开始比较,直到某一轮比较结束后没有进行交换,则排序结束
时间复杂度:O(n^n)
空间复杂度:O(1)
稳定性:稳定
JavaScript语言实现
function bubbleSort(arr){ var len = arr.length,k=0; for(var i=0;;i++){ k=0; for(var j=0;j<len-i-1;j++){ if(arr[j] > arr[j+1]){ var temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; k=1; } } if(k == 0) break; } console.log(arr); }
从一组数中选出最小的与第一个数据交换,再从剩余数据中继续选出最小的与第二个数据交换
时间复杂度:O(n^n)
空间复杂度:O(1)
稳定性:不稳定
JavaScript语言实现
function selectSort(arr){ var len = arr.length; for(var i=0;i<len;i++){ var index = i; for(var j=i+1;j<len;j++){ if(arr[j] < arr[index]){index = j;} } if(index != i){ var temp = arr[i]; arr[i] = arr[index]; arr[index] = temp; } } console.log(arr); }
将数据分为有序和无序,初始有序数据为第一个数,无序数据为剩余的,将无序数据循环插入到有序数据中
时间复杂度:O(n^n)
空间复杂度:O(1)
稳定性:稳定
JavaScript语言实现
function insertSort(arr){ var len = arr.length; for(var i=1;i<len;i++){ var temp = arr[i],j=i-1; while(j>=0 && arr[j]>temp){ arr[j+1] = arr[j]; j--; } arr[j+1] = temp; } console.log(arr); }
先选取数组中一个数作为基数,将其他数据与该基数比较,如果大于基数就排在基数的右侧,如果小于就排在基数的左侧,再分别对小于基数和大于基数的数组做快速排序
时间复杂度:O(nlogn)
空间复杂度:O(1ogn)
稳定性:不稳定
JavaScript语言实现
function quickSort(arr,start,end){ if(start < end){ var base = arr[start]; var temp; var i=start,j=end; do{ while(arr[i] < base && i < end){ i++; } while(arr[j] > base && j > start){ j--; } if(i <= j){ temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; i++; j--; } }while(i <= j); if(start < j){ sort4(arr,start,j); } if(end > i){ sort4(arr,i,end); } } console.log(arr); }
先将所有数据两两分组进行排序,再两两归并,重复进行直到所有数据归并成一个有序表
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:稳定
JavaScript语言实现
function mergeSort(arr){ function sort(array,first,last){ first = (first === undefined) ? 0 : first; last = (last === undefined) ? array.length-1 : last; if(last - first <1){return;} sort(arr,first,middle); sort(arr,middle+1,last); var f=first, m=middle, i, temp; while(f <= m && m + 1 <= last){ if(arr[f] >= arr[m+1]){ temp = arr[m+1]; for(i=m;i>=f;i--){ arr[i+1]=arr[i]; } arr[f] = temp; m++; }else { f++; } } return arr; } return sort(arr); }
将数据表示成完全二叉树的形式,并且以最大堆的方式排序,再一次交换最后一个最后一个元素和根元素,并且每一次都重新进行最大堆排序
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
JavaScript语言实现
function heapSort(array){ function swap(array,i,j){ var temp = array[i]; array[i] = array[j]; array[j] = temp; } /*最大堆调整*/ function maxHeapify(array,index,heapSize){ var iMax, iLeft, iRight; while(true){ iMax = index; iLeft = 2 * index + 1; iRight = 2 * (index + 1); if(iLeft < heapSize && array[index] < array[iLeft]){ iMax = iLeft; } if(iRight < heapSize && array[iMax] < array[iRight]){ iMax = iRight; } if(iMax != index){ swap(array,iMax,index); index = iMax; }else{break;} } } /*创建最大堆*/ function buildMaxHeap(array){ var i, iParent = Math.floor(array.length/2) - 1; for(i = iParent; i >= 0; i--){ maxHeapify(array,i,array.length); } } /*堆排序*/ function sort(array){ buildMaxHeap(array); for(var i = array.length - 1;i > 0; i--){ swap(array, 0, i); maxHeapify(array, 0, i); } return array; } return sort(array);
每次对相隔一定间隔的数进行插入排序
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
JavaScript语言实现
function shellSort(array){ function swap(array, i, k){ var temp = array[i]; array[i] = array[j]; array[j] = temp; } var length = array.length, gap = Math.floor(length / 2); while(gap > 0){ for(var i = gap; i < length; i++){ for(var j = i; j > 0; j -= gap){ if(array[j - gap] > array[j]){ swap(array, j - gap, j); }else { break; } } } gap = Math.floor(gap/2); } return array; }
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。