js implementation: sorting algorithm with complexity O(n^2) (bubble sort, simple selection sort, direct insertion sort)

Reference blog:
1. Summary of various sorting algorithms (comprehensive)
2. [Algorithm Summary] Top Ten Sorting Algorithms

(Assume that the sorting direction of the following algorithms is: from small to large. The number of array elements is: n)
insert image description here

1. Bubble sort

1. Principle:

——The number of elements to be arranged is n
(1) First, among the n elements, the largest element is arranged at the end, and the number of elements to be arranged is n-1. [The position of an element is determined]
(2) Arrange the second largest element among the n-1 elements to the end of the elements to be arranged , and the number of elements to be arranged is n-2. [The positions of the two elements are determined]
...
(n-1) Repeat the above steps n-1 times until the number of elements to be sorted is 1. [The position of n-1 elements is determined, so there is no need to determine the remaining elements, right? Saved a cycle]

Example: arr=[2,6,4,10,3]
(1) time: 2 is smaller than 6, no exchange; 6 is greater than 4, exchange; 6 is smaller than 10, no exchange; 10 is greater than 3, exchange
At this point the array becomes: [2,4,6,3, 10 ], the position of 10 is determined!
(2) pass: 2 is smaller than 4, do not exchange; 4 is smaller than 6, do not exchange; 6 is greater than 3, exchange; at this time the
array becomes: [2,4,3, 6,10 ], the position of 6 It's OK!
The third time: 2 is smaller than 4, do not exchange; 4 is larger than 3, exchange;
at this time the array becomes: [2,3, 4,6,10 ], the position of 4 is determined!
Step (4): 2 is smaller than 3, do not exchange
At this time, the array becomes: [2, 3, 4, 6, 10 ], the position of 3 is determined!
The position of 2 is naturally determined!

2. Code:

Putting the maximum value among the elements to be sorted at the end is actually to compare adjacent elements two by two, and if arr[j]>arr[j+1] , exchange their positions. Until j+1==arr.length-1 , a cycle ends

<script>
	let arr = [2,6,4,10,3];
	console.log(bubbleSort(arr));
	
	/**
	 * @param {array} arr
	 */
	function bubbleSort(arr){
    
    
		// 要确定原数组中,哪一个元素的位置
		for(let i=arr.length-1; i>0; i--){
    
    
			// 待排元素的范围:为什么 j 要小于i,为了保证 j+1 不越界
			for(let j=0; j<i; j++){
    
    
				if(arr[j]>arr[j+1]) swap(arr, j, j+1);
			}
		}
		return arr;
	}
	
	/**
	 * @param {array} arr
	 * @param {int} i
	 * @param {int} j
	 */
	function swap(arr, i, j){
    
    
		let temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
</script>

The exchange of positions between elements is very common in sorting algorithms. Therefore, here it is written as a swap function separately to increase the reusability of the code.

3. Optimization

If the array is replaced with a relatively ordered array, such as: [2,10,3,4,5,6], is it necessary to traverse so many times?
Obviously, this array only needs to be traversed once, and it is already in order.
[Thinking]: Can you add a flag change, when the array is already in order, end the loop.

<script>
	function bubbleSort(arr){
    
    
		for(let i=arr.length-1; i>0; i--){
    
    
			let change = false; // 标志位
			for(let j=0; j<i; j++){
    
    
				if(arr[j]>arr[j+1]){
    
    
					swap(arr, j, j+1);
					change = true; // 修改标志位
				}
			}
			if(change == false) break; // 标志位。结束循环
		}
		return arr;
	}
</script>

[2,10,3,4,5,6]
After the first loop ends, the array is already in order;
after the second loop ends, the flag bit will not be modified; so the loop will end and
the third loop will not be executed .

2. Simple selection sort

1. Principle

It is actually very similar to bubble sorting, and it is also a comparison between two pairs, but at this time it will not be exchanged, but will be recorded; after traversing the entire unsorted sequence, find the most value
in the unsorted sequence before exchanging. [It can be considered that selection sorting is an improvement of bubble sorting]

Assumption: The front of the array is a sorted sequence, and the back is an unsorted sequence.
Because it is sorted from small to large, we select the min value from the following sequence and arrange it at the end of the sorted sequence (ie: exchange with the last element of the sorted sequence) For example: arr=[
4,3 ,2,5,6]
(1) time: the sorted sequence is empty, [], the unsorted sequence is: [4,3,2,5,6], select the min value: 2, follow the sorted sequence The last element of , ie, is exchanged with 4. [2,3,4,5,6]
(2) time: the sorted sequence is empty, [2], the unsorted sequence is: [3,4,5,6], select the min value: 3, follow The last element of the sorted sequence, ie, is swapped with 3. [2,3,4,5,6]
(3) trip: the sorted sequence is empty, [2,3], the unsorted sequence is: [4,5,6], the selected min value: 4, follow The last element of the sorted sequence, ie, is swapped with 4. [2,3,4,5,6]
(4) time: the sorted sequence is empty, [2,3,4], the unsorted sequence is: [5,6], the min value is selected: 5, follow The last element of the sorted sequence, ie, is swapped with 5. [2,3,4,5,6]
(5th) trip: the sorted sequence is empty, [2,3,4,5], the unsorted sequence is: [6], select the min value: 6, follow The last element of the sorted sequence, ie, is swapped with 6. [2,3,4,5,6]

Even if the entire array is sorted, the min value will still be looked for as long as the unsorted sequence is not empty.
If there is any improvement over bubble sorting, it should be to reduce the number of exchanges?

2. Code

function selectSort(arr){
    
    
	// 已排序序列的右区间+1。
	// i是从0开始,已排序右区间最开始应该理解成-1?
	for(let i in arr){
    
    
		// 假设未排序序列的第一个元素为min
		let min_index = i;
		// 未排序序列的左区间
		for(let j=i; j<arr.length; j++){
    
    
			min_index = arr[j] < arr[min_index] ? j : min_index;
		}
		swap(arr, i, min_index);
	}
	return arr;
}

3. Insertion sort

1. Principle

It is also very similar to selection sort, dividing the array into two parts: the sorted sequence and the unsorted sequence. However, here the first element is sorted by default , and the previous selection sort is the default sorted sequence is empty (because in the selection sort, the position in the sorted sequence does not change once determined)

1. Take out the key of the first element of the unsorted sequence, and scan from the back to the front in the sorted sequence. Once the element arr[j] that is larger than the key is encountered, move it back one bit (because the key is larger than arr [ j] is small, it must be in the front, to make room for the key).
2. Until an element **arr[j]** is found that is smaller than the key, then the key is placed behind arr[j]. arr[j+1]=key
3. If no value smaller than key is found after traversing the sorted sequence, it means that the key should be placed at the front

2. Code

function insertSort(arr){
    
    
	// 未排序序列
	for(let i=1; i<arr.length; i++){
    
    
		// 记录下要排序的元素
		let key = arr[i];
		// 已排序序列
		for(var j=i-1; j>=0 && key < arr[i]; j--){
    
    
			arr[j+1] = arr[j];
		}
		// 跳出循环的条件:j<0 || 遇到比key小的值
		arr[j+1] = key;		
}

Guess you like

Origin blog.csdn.net/qq_38432089/article/details/124220384