一、排序算法
1、冒泡排序
function bubbleSort(arr){
let len = arr.length;
for(let i = 0; i < len; i++){
for(let j = 0; j < len - 1; j++){
if(arr[j] > arr[j+1]){
var item = arr[j];
arr[j] = arr[j+1];
arr[j+1] = item;
}
}
}
return arr;
}
2、改进后的冒泡排序
function bubbleSort(arr){
let len = arr.length;
for(let i = 0; i < len; i++){
for(let j = 0; j < len - 1 - i; j++){//减去外循环进行的轮数,即已经排序了的后面的数不用再和内循环进行比较
if(arr[j] > arr[j+1]){
var item = arr[j];
arr[j] = arr[j+1];
arr[j+1] = item;
}
}
}
return arr;
}
3、改进冒泡排序:当一次遍历前后数组不产生变化时,说明该数组已经有序,结束排序。
function sort(arr){
let len = arr.length,
flag;
for(let i = 0; i < len; i++){
flag = 0;
for(j = len - 1; j > i; j--){
if(arr[j] < arr[j-1]){
let temp = arr[j-1];
arr[j-1] = arr[j];
arr[j] = temp;
flag = 1;
}
}
if(!flag){
break;
}else{
flag = 0;
}
}
return arr;
}
4、选择排序
function selectionSort(arr){
let len = arr.length,
indexMin;
for(let i = 0; i < len; i++){//找到最小的放在第一位,次小的放在第二位,以此类推
indexMin = i;
for(let j = i; j < len; j++){
if(arr[indexMin] > arr[j]){
indexMin = j;
}
}
if(i !== indexMin){
let item = arr[i];
arr[i] = arr[indexMin];
arr[indexMin] = item;
}
}
return arr;
}
5、插入排序:对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入
function insertSort(arr){
let len = arr.length,
temp;
for(let i = 1; i < len; i++){
temp = arr[i];
j = i;
while(j > 0 && arr[j-1] > temp){
arr[j] = arr[j-1];
j--;
}
arr[j] = temp;
}
return arr;
}
6、二分插入排序:插入排序的一种优化实现, 通过二分法减少遍历时间
function insertSort(arr){
var len = arr.length, i, low, high, mid, temp;
for(i = 1; i < len; i++){
temp = arr[i];
low = 0;
high = i-1;
while(low <= high){
mid = parseInt((low+high)/2, 10);
if(temp < arr[mid])
high = mid-1;
else
low = mid+1;
}
//插入位置为low或者high+1
for(j = i-1; j >= high + 1; j--){
arr[j+1] = arr[j];
}
arr[j+1] = temp;
}
return arr;
}
7、希尔排序:先将整个待排序记录序列分割成若干个子序列,在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。
function sort(arr){
var len = arr.length,
gap = parseInt(len/2),
i,temp,j;
while(gap > 0){
for(i = gap; i < len; i++){
temp = arr[i];
j = i-gap;
while(j >= 0 && temp < arr[j]){
arr[j+gap] = arr[j];
j = j-gap;
}
arr[j+gap] = temp;
}
gap = parseInt(gap/2);
}
return arr;
}
8、堆排序
/* 将最大的元素调整到堆顶*/
function AdjustHeap(arr, pos, len){
var swap = arr[pos]; //保存当前节点
var child = pos * 2 + 1; //定位到当前节点的左边的子节点
while(child < len){ //递归遍历所有的子节点
//判断当前节点是否有右节点,若右节点较大,就采用右节点和当前节点进行比较
if(child + 1 < len && arr[child] < arr[child + 1]){
child += 1;
}
//比较当前节点和最大的子节点,小于就交换,交换后将当前节点定位到子节点上
if(arr[pos] < arr[child]){
arr[pos] = arr[child];
pos = child;
child = pos * 2 + 1;
}
else{
break;
}
arr[pos] = swap;
}
}
/* 构建堆:
* 满足:树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子结点的关键字。
* 实现:从最后一个拥有子节点的节点开始,将该节点和其他节点进行比较,将最大的数交换给该节点,
* 交换后再依次向前节点进行相同的交换处理,直到构建出大顶堆。
*/
function BuildHeap(arr){
for(var i=arr.length/2; i>=0; i--){ //构建大顶堆
AdjustHeap(arr, i, arr.length);
}
}
/*堆排序算法*/
function HeapSort(arr){
BuildHeap(arr); //构建堆
for(var i=arr.length-1; i>0; i--){ //从数组的尾部进行调整
var swap = arr[i]; //堆顶永远是最大的元素,将堆顶和尾部元素交换,最大元素就保存在尾部,并且不参与后面的调整
arr[i] = arr[0];
arr[0] = swap;
AdjustHeap(arr, 0, i); //将最大的元素进行调整,将最大的元素调整到堆顶
}
}
9、归并排序:将无序的数组拆成N部分进行有序处理,然后合并。
function sort(arr){
let len = arr.length;
if(len == 1) return arr;
let mid = Math.floor(len/2),
left = arr.slice(0, mid),
right = arr.slice(mid, len);
return merge(sort(left), sort(right));
}
function merge(left, right){
let result = [],
il = 0,
ir = 0;
while(il < left.length && ir < right.length){
if(left[il] < right[ir]){
result.push(left[il++]);
}else{
result.push(right[ir++]);
}
}
while(il < left.length){
result.push(left[il++]);
}
while(ir < right.length){
result.push(right[ir++]);
}
return result;
}
10、快速排序
在数据集之中,选择一个元素作为"基准"(pivot)。
所有小于"基准"的元素,都移到"基准"的左边;所有大于"基准"的元素,都移到"基准"的右边。
对"基准"左边和右边的两个子集,不断重复第一步和第二步,直到所有子集只剩下一个元素为止。
function sort(arr){
if(arr.length <= 1) return arr;
var pivot = parseInt(arr.length/2);
var temp = arr.splice(pivot,1)[0];
var left = [],right = [];
var i;
for(i=0;i<arr.length;i++){
if(arr[i] < temp){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
return sort(left).concat([temp],sort(right));
}
11、计数排序
查找待排序数组中最大和最小的元素
统计每个值为i的元素的出现次数
对所有计数开始累加(从min开始,每一项和前一项相加)
反向填充目标数组,将每个元素i放在新数组的第C[i]项,每放一个元素,计数-1.
function sort(arr){
var length = arr.length,i,count = [],result = [];
var min = arr[0],max = arr[0];
for(i=0;i<length;i++){
min = (min < arr[i])?min:arr[i];
max = (max > arr[i])?max:arr[i];
count[arr[i]] = count[arr[i]]?count[arr[i]]+1:1;
}
for(i=min;i<max;i++){
count[i+1] = (count[i+1] || 0) + (count[i] || 0);
}
for(i=length-1;i>=0;i--){
result[count[arr[i]]-1] = arr[i];
count[arr[i]]--;
}
return result;
}
复杂度分析
二、搜索算法
1、顺序搜索/线性搜索
function search(arr, item){
for(let i = 0; i < arr.length;i++){
if(arr[i] === item){
return i;
}
}
return -1;
}
2、二分搜索/查找
function search(arr, item){
var arr = sort(arr);//先进行排序
var low = 0,
high = arr.length -1,
mid, temp;
while(low <= high){
mid = Math.floor((low + high) / 2);
temp = arr[mid];
if(temp < item){
low = mid + 1;
}else if(temp > item){
high = mid - 1;
}else{
return mid;
}
}
return -1;
}