Sorting algorithm summary

Posted by Ajita on Sun, 23 Jan 2022 12:16:18 +0100

Sorting algorithm

The complexity of each sorting algorithm is as follows:

1. Bubble Sort

  1. Bubble sorting is a simple sorting algorithm.
  2. It repeatedly visits the sequence to be sorted, compares two elements at a time, and exchanges them if they are in the wrong order.
  3. A total of (arr.length - 1) rounds of sorting are performed, and the number of times of each round of sorting is reduced.
  4. The name of this algorithm comes from the fact that smaller elements will slowly "float" to the top of the sequence through exchange.

Sketch Map

code

		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = 0; j < arr.length - i - 1; j++) {
				if (arr[j] > arr[j + 1]) {
					temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
			}
		}
  1. If there is no exchange in a round of sorting, you can end the sorting in advance by setting flag.

2. Select Sort

  1. First, find the smallest element in the array,
  2. Second, swap it with the first element of the array (if the first element is the smallest element, it will swap with itself).
  3. Second, find the smallest of the remaining elements and swap it with the second element of the array.
  4. This goes back and forth until the entire array is sorted. This method is called selective sorting.

Sketch Map

code

	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			int min = arr[i]; // Assume that the current number is the lowest decimal
			int minIndex = i; // Write down the subscript of the lowest decimal
			// Compare with each of the following numbers, if there is a smaller number than the current one
			// Redefine min and minIndex
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[j] < min) {
					min = arr[j];
					minIndex = j;
				}
			}
			// If the current number of this round is not the minimum value, that is, the current number and the minimum value exchange positions
			if (minIndex != i) {
				arr[minIndex] = arr[i];
				arr[i] = min;
			}	
		}
	}

3. Insert Sort

3.1 basic ideas

In each step, a data to be sorted is inserted into the previously ordered sequence until all elements are inserted.

3.2 algorithm implementation

  1. Starting from the first element, the element can be considered to have been sorted;
  2. Take out the next element and scan from back to front in the sorted element sequence;
  3. If the element (sorted) is larger than the new element, move the element to the next position;
  4. Repeat step 3 until the sorted element is found to be less than or equal to the position of the new element;
  5. After inserting the new element into this position;
  6. Repeat steps 2 to 5.

Sketch Map

code

		public static void insertSort(int[] arr) {
		for (int i = 1; i < arr.length; i++) {
			int insertVal = arr[i]; // Number of to be inserted
			int insertIndex = i - 1; // The position to be inserted (compared) because it is traversed forward from this number
			// Traverse forward. If this element is greater than the number to be inserted, move this element backward
			// Exit the loop until an element smaller than the number to be inserted is found
			while(insertIndex >= 0 && insertVal < arr[insertIndex]) {
				arr[insertIndex + 1] = arr[insertIndex];
				insertIndex--; 
			}
			// At this point, arr [insertindex] < insertval
			// Therefore, the number to be inserted should be inserted at (insertIndex + 1)
			arr[insertIndex + 1] = insertVal;
		}
	}

4. Shell Sort

Hill sort is also an insert sort, also known as "narrow incremental sort".

4.1 basic ideas

Hill sort adopts the strategy of jumping grouping in the array. The array elements are divided into several groups through an increment, then grouped for insertion sorting, then gradually reduce the increment, and continue the insertion sorting operation by group until the increment is 1.

4.2 example


code

public static void shellSort(int[] arr) {
		int temp = 0;
		// Increment gap and gradually reduce the increment
		for (int gap = arr.length / 2; gap > 0; gap /= 2) {
			// Start with the gap element and sort the groups one by one
			for (int i = gap; i < arr.length; i++) {
				// Traverse all elements in each group (total gap group), step gap
				for (int j = i - gap; j >= 0; j -= gap) {
					// If the current element is larger than the element after adding the step, it is exchanged
					if (arr[j] > arr[j + gap]) {
						temp = arr[j];
						arr[j] = arr[j + gap];
						arr[j + gap] = temp;
					}
				}
			}
		}
	}

5. Merge Sort

Merge sort is a very typical application of Divide and Conquer.

5.1 basic ideas

The ordered subsequences are combined to obtain a completely ordered sequence; That is, each subsequence is ordered first, and then the subsequence segments are ordered.

5.2 algorithm implementation

  1. The input sequence with length n is divided into two subsequences with length n/2;
  2. The two subsequences are sorted by merging;
  3. Merge two sorted subsequences into a final sorting sequence.

Sketch Map

code

// Opening + closing method
	public static void mergeSort(int[] arr, int left, int right, int[] temp) {
		if (left < right) {
			int mid = (left + right) / 2; // Each time the intermediate index is changed, it is decomposed
			// Decompose recursively to the left
			mergeSort(arr, left, mid, temp);
			// Decompose recursively to the right
			mergeSort(arr, mid + 1, right, temp);
			// merge
			merge(arr, left, mid, right, temp);
		}
	}
	
	// Merging method
	/**
	 * 
	 * @param arr  Sorted original array
	 * @param left  Start index of left ordered sequence
	 * @param mid	Intermediate index
	 * @param right  Right index
	 * @param temp   Index as transit
	 */
	public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
		int i = left; // Start index of left ordered sequence
		int j = mid + 1; // Start index of the right ordered sequence
		int t = 0; // Points to the current index of the temp array
		
		// (1) Fill the left and right data into the temp array according to the rules
		//  Until one side is finished
		while (i <= mid && j <= right) {
			// If the current element on the left is smaller than the current element on the right, put the current element on the left into temp
			// Then t + +, i++
			if (arr[i] <= arr[j]) {
				temp[t] = arr[i];
				t += 1;
				i += 1;
			}else { //Conversely, put the current element on the right into temp
				temp[t] = arr[j];
				t += 1;
				j += 1;
			}
		}
		
		// (2) Fill all the data on the unfinished side into temp in turn
		while (i <= mid) {  //The left side is incomplete, and there are still elements left
			temp[t] = arr[i];
			t += 1;
			i += 1;
		}
		
		while (j <= right) {  //The left side is incomplete, and there are still elements left
			temp[t] = arr[j];
			t += 1;
			j += 1;
		}
		
		// (3) Copy the elements of temp array to arr
		t = 0;
		int tempLeft = left;
		
		while (tempLeft <= right) {
			arr[tempLeft] = temp[t];
			t += 1;
			tempLeft += 1;
		}				
	}	
}

6. Quick Sort

6.1 basic ideas

  1. First, take a number from the sequence as the reference number.
  2. In the partition process, all numbers larger than this number are placed on its right, and all numbers less than or equal to it are placed on its left.
  3. Repeat the second step for the left and right intervals until there is only one number in each interval.

6.2 algorithm implementation

Take the following arrangement as an example: 3 1 2 5 4 6 9 7 10 8
Start "detection" from both ends of the initial sequence "6 1 2 7 9 3 4 5 10 8". First find a number less than 6 from right to left, then find a number greater than 6 from left to right, and then exchange them.

  • First the sentry j began to move out.
  • Sentry j moves left step by step (i.e. j --) until he finds a number less than 6 and stops.
  • Next, sentry I moves to the right step by step (i.e. I + +) until he finds a number greater than 6 and stops.
  • Finally, sentry j stopped in front of the number 5 and sentry i stopped in front of the number 7.

  • Exchange the values of the elements pointed to by sentinel i and sentinel j
  • Here, the first exchange is over
  • The sentry j continued to move to the left. He found 4 (smaller than the benchmark 6, meeting the requirements) and stopped
  • Sentry i also continued to move to the right. He found 9 (larger than the benchmark number of 6, meeting the requirements) and stopped
  • Exchange again at this time

  • After the second exchange, the "detection" continues
  • Sentry j continued to move to the left. He found 3 (smaller than the benchmark 6, meeting the requirements) and stopped again
  • The sentry i keeps moving to the right. No! At this time, sentry i and sentry j meet, and sentry i and sentry j both come to 3
  • Indicates that the probe ends. We exchange the reference numbers 6 and 3

  • This is the real end of the first round of "detection".
  • At this time, taking the reference number 6 as the dividing point, the numbers on the left of 6 are less than or equal to 6, and the numbers on the right of 6 are greater than or equal to 6.

code

public static void quickSort(int[] arr, int left, int right) {
		int i = left;
		int j = right;
		int temp, t;
		if (left > right) {
			return;
		}
		
		temp = arr[left]; // Datum point
		
		while (i < j) {
			// The sentry j set out first until he found a number smaller than the reference point
			while (temp <= arr[j] && i < j) {
				j--;
			}
			// The sentry i set out until he found a number greater than the reference point
			while (temp >= arr[i] && i < j) {
				i++;
			}
			// Exchange when conditions are met
			if (i < j) {
				t = arr[i];
				arr[i] = arr[j];
				arr[j] = t;
			}
		}
		// Sentinels i and j meet and exchange the elements of this position with the reference position elements
		arr[left] = arr[i]; // At this time, the element of the position is placed in the reference position
		arr[i] = temp; // The datum element is placed at this position
		
		// Recursion: sort the queues on the left and right at i=j respectively
		quickSort(arr, left, i - 1);
		quickSort(arr, i + 1, right);
	}

7. Radix Sort

Cardinality sorting is an extension of bucket sorting.

7.1 basic ideas

Cut the integer into different numbers according to the number of digits, and then compare them respectively according to each number of digits.

7.2 algorithm implementation

  1. Initialize 10 buckets with subscripts 0 ~ 9;
  2. Take out the bits of each element to see which bucket it should be placed in;
  3. Take out the data in the order of buckets and put it into the original array;
  4. Repeat steps 1 and 2 for the tens, hundreds, thousands... Of each element.

Sketch Map

code

public static void radixSort(int arr[]) {

		// Get the number of digits of the largest number in the array
		int max = arr[0];
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > max) {
				max = arr[i];
			}
		}
		int maxLength = (max + "").length(); // Convert to a string and find the length, that is, the number of digits of the maximum number

		// Define a two-dimensional array, representing 10 buckets, and each bucket is a one-dimensional array
		int[][] bucket = new int[10][arr.length];

		// Define a one-dimensional array to record the number of data put into each bucket
		int[] bucketElementCounts = new int[10];

		for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
			// Sort the corresponding bits of each element: single bit -- > ten bit -- > hundred bit -- >
			for (int j = 0; j < arr.length; j++) {
				// Take out the value of the corresponding bit of each element
				int digitOfElement = arr[j] / n % 10;
				// Put it in the corresponding bucket
				bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
				bucketElementCounts[digitOfElement]++;
			}

			// Take out the data in the order of the bucket (array subscript) and put it into the original array
			int index = 0;
			for (int k = 0; k < bucketElementCounts.length; k++) { // Traverse each bucket
				if (bucketElementCounts[k] != 0) {
					for (int l = 0; l < bucketElementCounts[k]; l++) { // Traverse each data in the bucket
						arr[index++] = bucket[k][l];
					}
				}
				bucketElementCounts[k] = 0;
			}
			System.out.println("The first" + (i + 1) + "Round, the sorting result is:" + Arrays.toString(arr));
		}
	}

Topics: Algorithm