Data Structures and Algorithms - Sorting

1. Simple sorting

1. Bubble sort O(n^2)

Pairwise comparison, reverse order exchange

public static int[] bubbleSort(int[] arr) {
	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]) {
				arr[j]   = arr[j] ^ arr[j+1];
				arr[j+1] = arr[j] ^ arr[j+1];
				arr[j]   = arr[j] ^ arr[j+1];
			}
		}
	}
	return arr;
}

2. Selection sort O(n^2)

public static int[] selectSort(int[] arr) {
		int minIndex = -1;
		for (int i = 0; i < arr.length - 1; i++) {
			minIndex = i;
			for (int j = i + 1; j < arr.length; j++) {
				if(arr[minIndex] > arr[j]) {
					minIndex = j;
				}
			}
			if(i != minIndex) {
				arr[i]        = arr[minIndex] ^ arr[i];
				arr [minIndex] = arr [minIndex] ^ arr [i];
				arr[i]        = arr[minIndex] ^ arr[i];
			}
		}
		return arr;
	}

3. Insertion sort

Insert a record into an already sorted sorted table to get a new sorted table with records incremented by 1

public static int[] insertSort(int[] arr) {
		int sentinel;
		int index = -1;
		for (int i = 1; i < arr.length; i++) {
			sentinel = arr[i];
			if(arr[i] < arr[i - 1]) {
				// loop compare
				for (int j = 0; j < i; j++) {
					if(arr[i] < arr[j]) {
						index = j;
						break;
					}
				}
				// move
				for (int k = i; k > index; k--) {
					arr[k]   = arr[k] ^ arr[k-1];
					arr[k-1] = arr[k] ^ arr[k-1];
					arr[k]   = arr[k] ^ arr[k-1];
				}
				arr[index] = sentinel;
			}
		}
		return arr;
	}

Second, complex sorting

1. Hill sort O(n^(3/2))

The last increment value of the increment sequence must be equal to 1. The first half of the sequence is taken as the increment, and then halved each time to make the sequence basically orderly until the increment is 1.

It is not implemented, and an increment is added on the basis of direct sorting, which is an incremental comparison of sequences.

 

2. Heap sort O(nlogn)

It is an improvement on the basis of selection sorting, which builds the sequence into a large top heap, removes the top element of the heap, and rebuilds the remaining elements into a heap

Heap: Complete binary tree, the value of a node greater than or equal to its left and right nodes is called a large top heap, and less than or equal to a small top heap

public static int[] heapSort(int[] arr) {
		int len = arr.length;
		// build a large top heap
		for (int i = len / 2; i > 0 ; i--) {
			adjustHeap(arr, i-1, len);
		}
		
		for (int i = len - 1; i > 0; i--) {
			// swap the top data with the last data
			arr[0] = arr[0] ^ arr[i];
			arr[i] = arr[0] ^ arr[i];
			arr[0] = arr[0] ^ arr[i];
			
			adjustHeap(arr, 0, i);
		}
		return arr;
	}
	
	// adjust the heap structure
	public static int[] adjustHeap(int[] arr, int curInd, int len) {
		int tmp = arr[curInd];
		// The current node is compared with its own node to exchange child nodes: 2*curIndex 2*curIndex+1
		for(int i = (curInd + 1) * 2; i <= len; i++) {
			// Determine the size of the left and right nodes, and set i to the larger value index
			if (i < len && arr[i-1] < arr[i]) {
				++i;
			}
			
			// Compare parent node with larger child node
			if (arr[curInd] > arr[i-1]) {
				break;
			}
			arr [curInd] = arr [curInd] ^ arr [i-1];
			arr[i - 1]  = arr[curInd] ^ arr[i-1];
			arr [curInd] = arr [curInd] ^ arr [i-1];
			curInd = i - 1;
		}
		arr [curInd] = tmp;
		return arr;
	}

 

 3. Merge Sort

Use recursion and divide-and-conquer techniques to divide the data sequence into smaller and smaller half-sublists, then sort the half-sublists, and finally use recursive steps to merge the sorted half-sublists into larger and larger ordered sequences

 

public static int[] mergeSort(int[] arr, int first, int last) {
		if ((first + 1) < last) {
			int mid = (first + last) / 2;
			mergeSort(arr, first, mid);
			mergeSort(arr, mid, last);
			merge(arr, first, mid, last);
		}
		return arr;
	}
	
	public static void merge(int[] arr, int first, int mid, int last) {
		int[] tmp = new int[last - first];
		int indexL = first, indexR = mid, index = 0;
		
		while(indexL < mid && indexR < last) {
			if (arr[indexL] < arr[indexR]) {
				tmp[index] = arr[indexL];
				indexL++;
			} else {
				tmp[index] = arr[indexR];
				indexR++;
			}
			index ++;
		}
		
		while (indexL < mid) {
			tmp[index] = arr[indexL];
			index ++;
			indexL++;
		}
		
		while (indexR < last) {
			tmp[index] = arr[indexR];
			index ++;
			indexR++;
		}
		
		index = 0;
		for (int i = first; i < last; i++) {
			arr[i] = tmp[index];
			index ++;
		}
		
	}

 

 4. Quick sort O(nlogn)

After one sorting, it is divided into 2 parts, one part is larger than the other part

public static int[] quickSort(int[] arr, int low, int high) {
		int privot;
		if (low < high) {
			privot = partition(arr, low, high);
			quickSort(arr, low, privot - 1);
			quickSort(arr, privot + 1, high);
		}
		return arr;
	}

	public static int partition(int[] arr, int low, int high) {
		int privotKey = arr[low];
		while (low < high) {
			while (low < high && privotKey <= arr[high]) {
				high--;
			}
			swap(arr, low, high);
			while (low < high && privotKey >= arr[low]) {
				low++;
			}
			swap(arr, low, high);
		}
		return low;
	}

	public static void swap(int[] arr, int i1, int i2) {
		if (i1 != i2) {
			arr[i1] = arr[i1] ^ arr[i2];
			arr[i2] = arr[i1] ^ arr[i2];
			arr[i1] = arr[i1] ^ arr[i2];
		}
	}

 Optimization: random selection, middle of three numbers

Guess you like

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