Algorithm basis: sorting algorithm

One, sorting algorithm

There are many sorting algorithms, we only talk about the most representative ones: bubble sort, Hill sort, merge sort, quick sort.
Insert picture description here

1. Bubble Sort (Bubble Sort)

Realization ideas:

  1. Compare adjacent elements, and if the first one is greater than the second, swap the two.
  2. Make the same comparison for each adjacent element, from the first pair at the beginning to the last pair at the end. After the comparison, the largest element will be placed (bubble) to the last bit of the array.
  3. Each time the comparison is completed, the length of the array for the next comparison will be reduced by one. Because after comparing the arrays in one pass, the last element in the back is the maximum value of the previous elements, so the next round of comparison is meaningless.
  4. Continue to repeat the above steps for fewer and fewer elements each time until there is no pair of numbers to compare.

achieve:

function bubbleSort(arr){
    
    
	var 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 temp = arr[j+1];
				arr[j+1] = arr[j];
				arr[j] = temp;
			}
	}
	return arr;
}

Improvement 1: Set a flag variable pos, which is used to record the position of the last bit exchange in each pass. Since the records after the pos position are all swapped in place, it is enough to scan to the pos position when the next pass is sorted.

function bubbleSort(arr) {
    
    
	console.time("改进后冒泡排序耗时");
	while(i>0) {
    
    
		var pos = 0;//每趟开始时,无记录交换
		for(let j=0; j<i; j++){
    
    
			if(arr[j]>arr[j+1]) {
    
    
				pos=j;//记录交换的位置
				var temp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = temp;
			}
		}
		i=pos;//为下一趟排序准备
    }
    console.timeEnd('改进后冒泡排序耗时')return arr;
}

Improvement 2: In traditional bubble sorting, each sorting operation can only find one maximum or minimum value. We consider using the method of forward and reverse double bubbling in each sorting to get two final Value (largest and smallest), so that the number of sorting passes is almost reduced in general.

function bublleSort(arr) {
    
    
	var low = 0;
	var high = arr.length-1;//设置变量的初始值
	var temp, j;
	console.time('2.改进后冒泡排序耗时');
	while(low<high) {
    
    
		for(j=low; j<high; j++) {
    
    
			if (arr[j]> arr[j+1]) {
    
     
				tmp = arr[j]; 
				arr[j]=arr[j+1];
				arr[j+1]=tmp; 
			} 
			--high; //修改high值, 前移⼀位
		}
		for (j=high; j>low; --j) {
    
    //反向冒泡,找到最⼩者 
			if (arr[j]<arr[j-1]) {
    
     
				tmp = arr[j]; 
				arr[j]=arr[j-1];
				arr[j-1]=tmp; 
			} 
			++low; //修改low值,后移⼀位
		}
	}
	console.timeEnd('2.改进后冒泡排序耗时'); 
	return arr3;
}

2. Hill sort (Shell Sort)

Shell proposed in 1959; the first breakthrough O(n^2) sorting algorithm; it is an improved version of simple insertion sort; the difference between it and insertion sort is that it will compare elements that are farther apart first, Hill sort Also called reduced incremental sort.

Algorithm introduction: The core of Hill sorting is the setting of interval sequence. The interval sequence can be set in advance, or the interval sequence can be dynamically defined.

Realization idea:
First divide the entire sequence of records to be sorted into subsequences for direct insertion sorting, the specific algorithm description:

  1. Choose an incremental sequence t1, t2,..., tk, where ti>tj, tk=1;
  2. Sort the sequence k times according to the number of incremental sequences k;
  3. For each sorting, according to the corresponding increment ti, the sequence to be sorted is divided into sub-sequences of degree m, and each sub-table is directly inserted and sorted. When only the increment factor is 1, the entire sequence is treated as a table, and the table length is the length of the entire sequence.

Code:

function shellSort(arr) {
    
     
	var len = arr.length, temp, gap = 1; 
	console.time('希尔排序耗时:'); 
	while(gap < len/5) {
    
     //动态定义间隔序列 
		gap =gap*5+1; 
	}
	for (gap; gap > 0; gap = Math.floor(gap/5)) {
    
     
		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; 
		} 
	}
	console.timeEnd('希尔排序耗时:'); 
	return arr; 
}
var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; 
console.log(shellSort(arr));//[2, 3, 4, 5, 15, 19, 26, 27, 36, 38, 44, 46, 47, 48, 50]

Insert picture description here

3. Merge Sort (Merge Sort)

Like selection sort, the performance of merge sort is not affected by the input data, but it performs much better than selection sort because it is always O(n log n) time complexity. The price is the need for additional memory space.

Merge sorting is an effective sorting algorithm built on merge operations. This algorithm is a very typical application of Divide and Conquer. Merge sort is a stable sorting method. Combine existing ordered sub-sequences to obtain a completely ordered sequence; that is, first make each sub-sequence in order, and then make the sub-sequences in order. If two ordered lists are merged into one ordered list, it is called 2-way merge.

Realization ideas:

  1. Divide the input sequence of degree n into two sub-sequences of degree n/2.
  2. Use merge sort for these two subsequences.
  3. Combine the two sorted subsequences into a final sorted sequence.

Code:

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 = []; 
	console.time('归并排序耗时'); 
	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()); 
	console.timeEnd('归并排序耗时'); 
	return result; 
}

var arr=[3,44,38,5,47,15,36,26,27,2,46,4,19,50,48]; 
console.log(mergeSort(arr));

4. Quick Sort (Quick Sort)

The basic idea of ​​quick sorting: separate the records to be sorted into two separate parts through a sorting pass. The keywords of one part of the records are smaller than the keywords of the other part, and you can continue to perform the two parts of the records separately Sort to achieve order of the entire sequence.

Realization ideas:

  1. Select the middle item from the array as the pivot;
  2. Create two pointers, the left one points to the first item of the array, and the right one points to the last item of the array. Move the left pointer until we find an element smaller than the pivot size, and then move the right pointer until we find an element smaller than the pivot size. Then swap them and repeat the process until the left pointer exceeds the right pointer. This process is that the values ​​of the pivot size are all arranged before the pivot, and the values ​​of the pivot size are all arranged after the pivot. This step is called the division operation.
  3. Next, the algorithm repeats the previous two steps for the divided small arrays (subarrays composed of smaller pivotal values ​​and subarrays composed of larger pivotal values) until the array is completely sorted.
// 快速排序 
const quickSort = (function() {
    
     // 默认状态下的⽐较函数 
	function compare(a, b) {
    
     if (a === b) {
    
     return 0 }
	return a < b ? -1 : 1 
}
function swap(array, a, b) {
    
     
	[array[a], array[b]] = [array[b], array[a]] 
}
// 分治函数 
function partition(array, left, right) {
    
     // ⽤index取中间值⽽⾮splice 
	const pivot = array[Math.floor((right + left) / 2)] 
	let i = left 
	let j = right 
	while (i <= j) {
    
     
		while (compare(array[i], pivot) === -1) {
    
     
			i++ 
		}
		while (compare(array[j], pivot) === 1) {
    
     
			j-- 
		}
		if (i <= j) {
    
     
			swap(array, i, j) 
			i++ 
			j-- 
		} 
	}
	return i 
}
// 快排函数 
function quick(array, left, right) {
    
     
	let index 
	if (array.length > 1) {
    
     
		index = partition(array, left, right) 
		if (left < index - 1) {
    
     
			quick(array, left, index - 1) 
		}
		if (index < right) {
    
     
			quick(array, index, right) 
		} 
	}
	return array 
}
return function quickSort(array) {
    
     return quick(array, 0, array.length - 1) }

Guess you like

Origin blog.csdn.net/imagine_tion/article/details/112181046
Recommended