数据结构常用算法--前端

一、排序算法

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、快速排序

扫描二维码关注公众号,回复: 2147331 查看本文章

在数据集之中,选择一个元素作为"基准"(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;
}




猜你喜欢

转载自blog.csdn.net/wwjwy123/article/details/80880550