@hzy1123581324/z-view-ui
Version:
z-view-ui是使用vue3开发的组件,开发中,有部分组件功能未实现,慎用
469 lines (363 loc) • 14.5 kB
JavaScript
//快速排序
let quickSort = arr => {
if (arr.length <= 1) { return arr; }
let pivotIndex = Math.floor(arr.length / 2);
let pivot = arr.splice(pivotIndex, 1)[0];//splice返回的是数组
let [left, right] = [[], []];
for (let i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
function quickSort(arr) {
//如果数组的个数小于等于1,就返回该数组
if (arr.length <= 1) {
return arr;
} else {
//否则,取得该数组的中间位置,保存在变量c中
var c = Math.floor(arr.length / 2);
//将变量c位置的值取出来存入变量center中
var center = arr.splice(c, 1)[0];
//声明两个空数组left、right
var left = []; var right = [];
//然后遍历arr数组将每个数与center做比较,大的放在right中,小的放在left中
for (var i = 0; i < arr.length; i++) {
if (arr[i] <= center) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
//最后返回左边和右边的数组,并对其做相同操作,直到递归完成
return quickSort(left).concat(center).concat(quickSort(right));
}
}
//另一种写法
function quickSort(arr, left, right) {
var len = arr.length,
partitionIndex,
left = typeof left != 'number' ? 0 : left,
right = typeof right != 'number' ? len - 1 : right;
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) { //分区操作
var pivot = left, //设定基准值(pivot)
index = pivot + 1;
for (var 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) {
var temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//冒泡排序
// 冒泡排序须知:
// 作为最简单的排序算法之一,冒泡排序给我的感觉就像Abandon在单词书里出现的感觉一样,每次都在第一页第一位,所以最熟悉。。。冒泡排序还有一种优化算法,就是立一个flag,当在一趟序列遍历中元素没有发生交换,则证明该序列已经有序。但这种改进对于提升性能来说并没有什么太大作用。。。
// 什么时候最快(Best Cases):
// 当输入的数据已经是正序时(都已经是正序了,我还要你冒泡排序有何用啊。。。。)
// 什么时候最慢(Worst Cases):
// 当输入的数据是反序时(写一个for循环反序输出数据不就行了,干嘛要用你冒泡排序呢,我是闲的吗。。。)
// function bubbleSort(arr) {
// var len = arr.length;
// for (var i = 0; i < len - 1; i++) {
// for (var j = 0; j < len - 1 - i; j++) {
// if (arr[j] > arr[j+1]) { // 相邻元素两两对比
// var temp = arr[j+1]; // 元素交换
// arr[j+1] = arr[j];
// arr[j] = temp;
// }
// }
// }
// return arr;
// }
let bubbleSort = 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]) {// 相邻元素两两对比
[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];// 元素交换
}
}
}
return arr;
}
//选择排序
// 选择排序须知:
// 在时间复杂度上表现最稳定的排序算法之一,因为无论什么数据进去都是O(n²)的时间复杂度。。。所以用到它的时候,数据规模越小越好。唯一的好处可能就是不占用额外的内存空间了吧。
// function selectionSort(arr) {
// var len = arr.length;
// var minIndex, temp;
// for (var i = 0; i < len - 1; i++) {
// minIndex = i;
// for (var j = i + 1; j < len; j++) {
// if (arr[j] < arr[minIndex]) { // 寻找最小的数
// minIndex = j; // 将最小数的索引保存
// }
// }
// temp = arr[i];
// arr[i] = arr[minIndex];
// arr[minIndex] = temp;
// }
// return arr;
// }
let selectionSort = arr => {
let len = arr.length;
let [minIndex, temp] = [];
for (let i = 0; i < len - 1; i++) {
[minIndex] = [i];
for (let j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { // 寻找最小的数
[minIndex] = [j]; // 将最小数的索引保存
}
}
[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
}
return arr;
}
//插入排序
// 插入排序的代码实现虽然没有冒泡排序和选择排序那么简单粗暴,但它的原理应该是最容易理解的了,因为只要打过扑克牌的人都应该能够秒懂。当然,如果你说你打扑克牌摸牌的时候从来不按牌的大小整理牌,那估计这辈子你对插入排序的算法都不会产生任何兴趣了。。。
// 插入排序和冒泡排序一样,也有一种优化算法,叫做拆半插入。对于这种算法,得了懒癌的我就套用教科书上的一句经典的话吧:感兴趣的同学可以在课后自行研究。。。
function insertionSort(arr) {
var len = arr.length;
var preIndex, current;
for (var 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;
}
/**********插入排序算法***********/
function insertSort(arr) {
//遍历数组
for (var i = 1; i < arr2.length; i++) {
//声明一个变量用来记录开始比较的位置,并将i位置的值保存在变量t中
var t = arr2[i];
//声明一个变量用来记录i前一个位置保存在变量p中
var p = i - 1;
//如果p不为负数且t的值不小于p位置的值就无限循环
while (p >= 0 && t < arr2[p]) {
//让p位置的值和p+1位置的值交换位置
arr2[p + 1] = arr2[p];
//然后让p自减
p--;
}
//当退出循环的时候讲t的值保存在p+1的位置
arr2[p + 1] = t;
}
}
//归并排序
// 作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:
// 1.自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第2种方法)
// 2.自下而上的迭代
function mergeSort(arr) { // 采用自上而下的递归方法
var len = arr.length;
if (len < 2) {
return arr;
}
var middle = Math.floor(len / 2),
left = arr.slice(0, middle),
right = arr.slice(middle);
return merge(mergeSort(left), mergeSort(right));
}
function merge(left, right) {
var result = [];
while (left.length && right.length) {
if (left[0] <= right[0]) {
result.push(left.shift());
} else {
result.push(right.shift());
}
}
while (left.length)
result.push(left.shift());
while (right.length)
result.push(right.shift());
return result;
}
// 希尔排序须知:
// 希尔排序是插入排序的一种更高效率的实现。它与插入排序的不同之处在于,它会优先比较距离较远的元素。希尔排序的核心在于间隔序列的设定。既可以提前设定好间隔序列,也可以动态的定义间隔序列。动态定义间隔序列的算法是《算法(第4版》的合著者Robert Sedgewick提出的。在这里,我就使用了这种方法。
// 希尔排序JavaScript代码实现:
function shellSort(arr) {
var len = arr.length,
temp,
gap = 1;
while (gap < len / 3) { //动态定义间隔序列
gap = gap * 3 + 1;
}
for (gap; gap > 0; gap = Math.floor(gap / 3)) {
for (var i = gap; i < len; i++) {
temp = arr[i];
for (var j = i - gap; j > 0 && arr[j] > temp; j -= gap) {
arr[j + gap] = arr[j];
}
arr[j + gap] = temp;
}
}
return arr;
}
// 堆排序须知:
// 堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
// 1.大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列
// 2.小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列
// 堆排序JavaScript代码实现:
var len; //因为声明的多个函数都需要数据长度,所以把len设置成为全局变量
function buildMaxHeap(arr) { //建立大顶堆
len = arr.length;
for (var i = Math.floor(len / 2)-1; i >= 0; i--) {
heapify(arr, i);
}
}
function heapify(arr, i) { //堆调整
var left = 2 * i + 1,
right = 2 * i + 2,
largest = i;
if (left < len && arr[left] > arr[largest]) {
largest = left;
}
if (right < len && arr[right] > arr[largest]) {
largest = right;
}
if (largest != i) {
swap(arr, i, largest);
heapify(arr, 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--;
heapify(arr, 0);
}
return arr;
}
// 计数排序须知:
// 计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。
// 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
// 计数排序JavaScript代码实现:
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;
}
// 桶排序须知:
// 桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。
// 为了使桶排序更加高效,我们需要做到这两点:
// 1.在额外空间充足的情况下,尽量增大桶的数量
// 2.使用的映射函数能够将输入的N个数据均匀的分配到K个桶中
// 同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
// 什么时候最快(Best Cases):
// 当输入的数据可以均匀的分配到每一个桶中
// 什么时候最慢(Worst Cases):
// 当输入的数据被分配到了同一个桶中
// 桶排序JavaScript代码实现:
function bucketSort(arr, bucketSize) {
if (arr.length === 0) {
return arr;
}
var i;
var minValue = arr[0];
var maxValue = arr[0];
for (i = 1; i < arr.length; i++) {
if (arr[i] < minValue) {
minValue = arr[i]; //输入数据的最小值
} else if (arr[i] > maxValue) {
maxValue = arr[i]; //输入数据的最大值
}
}
//桶的初始化
var DEFAULT_BUCKET_SIZE = 5; //设置桶的默认数量为5
bucketSize = bucketSize || DEFAULT_BUCKET_SIZE;
var bucketCount = Math.floor((maxValue - minValue) / bucketSize) + 1;
var buckets = new Array(bucketCount);
for (i = 0; i < buckets.length; i++) {
buckets[i] = [];
}
//利用映射函数将数据分配到各个桶中
for (i = 0; i < arr.length; i++) {
buckets[Math.floor((arr[i] - minValue) / bucketSize)].push(arr[i]);
}
arr.length = 0;
for (i = 0; i < buckets.length; i++) {
insertionSort(buckets[i]); //对每个桶进行排序,这里使用了插入排序
for (var j = 0; j < buckets[i].length; j++) {
arr.push(buckets[i][j]);
}
}
return arr;
}
// 基数排序须知:
// 基数排序有两种方法:
// 1.MSD 从高位开始进行排序
// 2.LSD 从低位开始进行排序
// 基数排序 vs 计数排序 vs 桶排序
// 这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
// 基数排序:根据键值的每位数字来分配桶
// 计数排序:每个桶只存储单一键值
// 桶排序:每个桶存储一定范围的数值
// 基数排序JavaScript代码实现:
//LSD Radix Sort
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;
}