Algorithms - Selection Sort, Insertion Sort, and Hill Sort (Improved Insertion Sort)

selection sort

First, find the smallest element in the array, and second, swap it with the first element of the array (if the first element is the smallest element, then swap it with itself). Again, find the smallest element among the remaining elements, swap it with the second element of the array. And so on until the entire array is sorted.

Performance : The time efficiency of the algorithm depends on the number of comparisons. For an array of length N, selection sort requires about N²/2 comparisons and N swaps.

Features : 1. The running time has nothing to do with the input : for example, even if an ordered sequence is input, it will be compared and exchanged like a random sequence.

           2. The data movement is the least : a total of N exchanges, that is, the number of exchanges and the size of the array are linear. No other algorithm has this feature, most of them are linear logarithmic or square level.

The function is implemented as follows:

public class Selection {
	public static void sort(Comparable[] a) {
		//将a[]按升序排列
		int N=a.length;
		for(int i=0;i<N;i++) {
			int min=i;
			for(int j=i+1;j<N;j++) {
				if(less(a[j],a[min]))min=j;
			}
			exch(a,i,min);
		}
	}
}

Insertion sort

Just like how people usually arrange bridge cards, they come one by one, inserting each card into its proper place among the other already ordered cards.

In the computer implementation, to make room for the element to be inserted, we need to shift all remaining elements one bit to the right before inserting. This algorithm is called insertion sort.

Unlike selection sort, insertion sort takes time depending on the initial order of elements in the input. For example, sorting a large array that is already sorted (or nearly sorted) will be much faster than sorting a random or reversed array.

Performance (length N with no duplicate primary keys): Average case - N²/4 comparisons and N²/4 swaps

                                                    Worst case - N²/2 comparisons and N²/2 swaps

                                                    Best case - N-1 comparisons and 0 swaps

The function is implemented as follows:

public class Insertion {
	public static void sort(Comparable[] a) {
		//将a[]按升序排列
		int N=a.length;
		for(int i=0;i<N;i++) {
			//将a[i]插入到a[i-1],a[i-2],a[i-3]...之中
			for(int j=i;j>0&&less(a[j],a[j-1]);j--)
			exch(a,i,j-1);
		}
	}
}

Because each element is looped from the beginning to the end, when looping to an element (set as a), it is already an ordered sequence on the left, and an unordered sequence on the right, just turn the a element to the right and each element in turn Compare, when you find it is greater than some element (let's set b), just insert a after b.

Partially ordered : An array is said to be partially ordered if the number of inversions in the array is less than some multiple of the array size.

Insertion sort works well for partially sorted arrays, while selection sort is not (since speed is independent of input).

Improvements to Insertion Sort: Hill Sort

Insertion sort is slow for large out-of-order arrays, because it only swaps adjacent elements (see insertion sort implementation code), so elements can only be moved from one end of the array to the other little by little. For example, if the element with the smallest primary key is right at the end of the array, it would take N-1 moves to get it to the correct position. Hill sort simply improves insertion sort for speed, swaps non-adjacent elements to sort parts of the array, and finally uses insertion sort to sort the partially sorted array.

The idea of ​​Hill sort is to make any elements with interval h in the array are ordered pairs. Such an array is called an h-ordered array .

In the implementation here, h is first embodied as an h sequence , such as: 1, 4, 13, 40, 121, 364, 1093...

Implementation: We first turn the random number sequence into a 364 (assuming that the maximum h of this sequence can take 364) an ordered sequence, and realize that the elements with an interval of 364 in the array are all ordered pairs; then turn the sequence into a 121 ordinal sequence; ... until h becomes 1, realizing the ordered sequence we seek.

In this way, we can sort the array for any 1-terminated h sequence, which is the Hill sort.

The function is implemented as follows:

public class Shell {
	public static void sort(Comparable[] a) {
		//将a[]按升序排列
		int N=a.length;
		int h=1;
		while(h<N/3)h=3*h+1;//1,4,13,40,121,364,1093...取得适合此序列的最大h值
		while(h>1) {//每次循环都将数组变为h有序数组
			for(int i=h;i<N;i++) {
				//将a[i]插入到a[i-h],a[i-2*h],a[i-2*h]...之中
				//划重点!!此处体现了插入排序,希尔排序只是将插入排序移动增量1变为了h
				for(int j=i;j>=h&&less(a[j],a[j-h]);j-=h;)
					exch(a,j,j-h);
			}
			h=h/3;
		}
	}
}

Performance : The performance of Hill sort is difficult to demonstrate, but only for the performance of the above code, in the worst case, its number of comparisons is proportional to the power of N(3/2). From insertion sort to Hill sort, a small change breaks through the square-level operating barrier.

The running time of Hill sort is acceptable for medium sized arrays, the code size is small, and no additional memory space is required. We learn more efficient algorithms later, but except for very large N, they may only be twice as fast as Hill sort, and more complicated.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325373125&siteId=291194637