快速排序
快速排序即找一基准,小于的放在左数组,大于的放在右数组,并连接,进行递归。
function quickSort(arr){
if(arr.length<=1){//如果数组只有一个数,就直接返回;
return arr;
}
var num=Math.floor(arr.length/2);//找到中间数的索引值,如果是浮点数,则向下取整
var newValue=arr.splice(num,1);//找到中间数的值
var left=[],right=[];
for(var i=0;i<arr.length;i++){
if(arr[i]<newValue){
left.push(arr[i]);//基准点的左边的数传到左边数组
}else{
right.push(arr[i]);//基准点的右边的数传到右边数组
}
}
return quickSort(left).concat(newValue,quickSort(right));//递归不断重复比较,concat即连接数组
}
console.log(quickSort([21,5,45,12,56,8]));
堆排序
堆排序类似完全二叉树。利用堆顶元素最大的性质(但同行之间顺序未排),将堆顶元素取出放入新数组(循环时len–,视为新数组)中,将堆底元素放置堆顶,并重构,循环。
var len;
function buildMaxHeap(arr) { //建堆
len = arr.length;
// [n/2-1]表示的是最后一个有子节点 (本来是n/2(堆从1数起),但是这里arr索引是从0开始,所以-1)
for (var i = Math.floor(len/2)-1; i>=0; i--) {
maxHeapify(arr, i);
}
//对每一个节点(非叶节点),做堆调整
}
function maxHeapify(arr, i) { //堆调整
var left = 2*i+1,
right = 2*i+2,
largest = i; //i为该子树的根节点
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) { //即上面的if中有一个生效了
swap(arr, i, largest); //交换最大的为父节点
maxHeapify(arr, largest); //交换后,原值arr[i](往下降了)(索引保存为largest),
//作为根时,子节点可能比它大,因此要继续调整
}
}
function swap(arr, i, j) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
function heapSort(arr) {
buildMaxHeap(arr);
for (var i = arr.length-1; i > 0; i--) {
swap(arr, 0, i);
len--;
maxHeapify(arr, 0);
}
return arr;
}
var arr = [46,12,33,72,68,19,80,33];
heapSort(arr)
console.log(' after: ' + arr);
计数排序
计数排序要求数据集必须是已确定范围的整数。
统计数组中每个值为i的元素出现的次数,存入数组C的第i项,填充数组。
function countingSort(arr, maxValue) {
var bucket =new Array(maxValue + 1),
sortedIndex = 0;
arrLen = arr.length,
bucketLen = maxValue + 1;
for (var i = 0; i < arrLen; i++) {
if (!bucket[arr[i]]) {
bucket[arr[i]] = 0;
}
bucket[arr[i]]++;
}
for (var j = 0; j < bucketLen; j++) {
while(bucket[j] > 0) {
arr[sortedIndex++] = j;
bucket[j]--;
}
}
return arr;
}
桶排序
桶排序利用了空间换时间的思想。即假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序,依次取出桶中数据。
/**
* 桶排序
* @param {Array} arr
* @param {Number} bucketSize
*/
function bucketSort(arr, bucketSize = 5) {
if (arr.length < 2) return arr;
const buckets = createBucket(arr, bucketSize);
return sortBuckets(buckets);
}
/**
* @description:
* @param {Array} arr=待排序数据
* @param {Number} bucketSize=桶大小
* @return:
*/
function createBucket(arr, bucketSize) {
let minValue = arr[0];
let maxValue = arr[0];
// 找出数据中最大值和最小值,根据桶的大小用来划分桶的个数和区间
for (let i = 1; i < arr.length; i++) {
if (arr[i] < minValue) {
minValue = arr[i];
} else if (arr[i] > maxValue) {
maxValue = arr[i];
}
}
// 桶的个数
const bucketCount = Math.ceil((maxValue - minValue) / bucketSize);
// 创建桶,用二维数组来存储
const buckets = [];
for (let i = 0; i <= bucketCount; i++) {
buckets[i] = [];
}
// 计算把数据放到哪个桶
for (let i = 0; i < arr.length; i++) {
let bucketIndex = Math.floor((arr[i] - minValue) / bucketSize);
buckets[bucketIndex].push(arr[i]);
}
return buckets;
}
/**
* @description: 排序桶
* @param {Array} buckets
* @return:
*/
function sortBuckets(buckets) {
const sortArray = [];
for (let i = 0; i < buckets.length; i++) {
if (buckets[i] != null) {
const sortBucket = insertionSort(buckets[i]);
sortArray.push(sortBucket);
}
}
return sortArray;
}
/**
* @description: 插入排序
* @param {Array} arr
* @return: 排好序的arr
*/
function insertionSort(arr) {
if (arr.length < 2) return arr;
for (let i = 1; i < arr.length; i++) {
let key = arr[i]; // 第一个元素已排好序,从第二个开始比较插入
let j = i - 1;
for (; j >= 0; j--) {
if (arr[j] > key) {
arr[j + 1] = arr[j]; // 比较,较大者,往后移
} else {
break;
}
}
arr[j + 1] = key; // 插入对应的位置
}
return arr;
}
// 随机生成1000000个[1,100]区间内的整数
let arr1 = Array.from(
{ length: 1000000 },
item => (item = Math.floor(Math.random() * Math.floor(100) + 1))
);
console.time("timer");
// console.log(`排序前的数据:${arr1}, 排序后的数据:${bucketSort(arr1, 5)}`);
bucketSort(arr1, 1); // 桶越小,排序越快,即桶个数越多,排序越快
console.timeEnd("timer");
基数排序
基数排序即按照键值的每位数字分配桶。
先按照个位分配10个桶中,后按顺序分到另一桶,再按照十位分配到10个桶中,进行循环。
var counter = [];
function radixSort(arr, maxDigit) {
var mod = 10;
var dev = 1;
for (var i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
for(var j = 0; j < arr.length; j++) {
var bucket = parseInt((arr[j] % mod) / dev);
if(counter[bucket]==null) {
counter[bucket] = [];
}
counter[bucket].push(arr[j]);
}
var pos = 0;
for(var j = 0; j < counter.length; j++) {
var value = null;
if(counter[j]!=null) {
while ((value = counter[j].shift()) != null) {
arr[pos++] = value;
}
}
}
}
return arr;
}
424

被折叠的 条评论
为什么被折叠?



