Data structure and algorithm-bubble sort, selection sort, insertion sort, hill sort, quick sort, radix sort, merge sort, heap sort

Bubble Sort

    By treating the sorting sequence from front to back (starting from the element with the smaller subscript), compare the values ​​of the adjacent elements in turn, if the reverse order is found, exchange, so that the element with the larger value gradually moves from front to back (from small to large) Sort, big numbers move back, small numbers move forward)
Insert picture description here

public static void BubbleSort(int[] array) {
    
    
	int temp;
	boolean isProcess;
	// n个数进行n-1趟排序,n-1个数确定了最后一个就确定了
	for (int i = 0; i < array.length-1; i++) {
    
    
		isProcess = false;
		for (int j = 0; j < array.length-i-1; j++) {
    
       //最后的倒数第i+1个不用比较
			if (array[j] > array[j+1]) {
    
       //交换
				temp = array[j];
				array[j] = array[j+1];
				array[j+1] = temp;
				isProcess = true;
			}
		}
		if (!isProcess) {
    
    
			break;
		}
	}
}

Select sort

    Select the minimum value from array[0] ~ array[n-1] for the first time, and exchange with array[0].
    Select the smallest value from array[1] ~ array[n-1] for the second time, and exchange with array[1].
    Select the minimum value from array[i-1] ~ array[n-1] for the i-th time and exchange with array[i-1].
    And so on, a total of n-1 times.
Insert picture description here

public static void SelectionSort(int[] array) {
    
    
	int min, index;
	for (int i = 0; i < array.length-1; i++) {
    
    
		min = array[i];
		index = i;
		for (int j = i + 1; j < array.length; j++) {
    
    
			if (array[j] < min) {
    
    
				min = array[j];
				index = j;
			}
		}
		if (index != i) {
    
    
			array[index] = array[i];
			array[i] = min;
		}
	}
}

Insertion sort

    Consider the n elements to be sorted as an ordered list and an unordered list. At the beginning, the ordered list contains only 1 element, and the unordered list contains n-1 elements. In the sorting process, each time the first element is taken from the unordered list, it is inserted into the appropriate position in the ordered list, making it a new ordered list.
Insert picture description here

public static void InsertSort(int[] array) {
    
    
	int temp, index;
	for (int i = 1; i < array.length; i++) {
    
    
		index = i;
		temp = array[index];
		while (index > 0 && temp < array[index - 1]) {
    
    
		// 前面的数比当前数大,则当前数继续往前移
			array[index] = array[index - 1];
			index--;
		}
		array[index] = temp;
	}
}

Hill sort

    The arrays are grouped by a certain increment, and each group is sorted by the direct insertion algorithm; as the increment decreases, each group contains more and more numbers. When the increment decreases to 1, the entire file is divided into one group.

public static void ShellSort(int[] array) {
    
    
	int increment = array.length, temp, index;
	while ((increment /= 2) != 0) {
    
    
		for (int i = increment; i < array.length; i++) {
    
    
			index = i;
			temp = array[index];
			while (index - increment >= 0 && temp < array[index - increment]) {
    
    
				array[index] = array[index - increment];
				index-=increment;
			}
			array[index] = temp;
		}
	}
}

Quick sort

    The basic idea of ​​quick sorting is: (digging holes and filling numbers + divide and conquer)

  1. First take a number from the number sequence as the reference number.
  2. In the partitioning process, all numbers larger than this number are placed to the right, and numbers less than or equal to it are placed to the left.
  3. Repeat the second step for the left and right intervals until there is only one number in each interval.
public static void QuickSort(int[] array, int low, int high) {
    
    
	if (low < high) {
    
    
		int temp = array[low], i = low, j = high;
		//选取temp为基准,array[low]可以看成一个坑
		while (i < j) {
    
    
			while (i < j && temp <= array[j])
				j--;   //从右向左找小于temp的数来填坑
			if (i < j)
				array[i++] = array[j];   //填坑array[i],形成新坑array[j]
			while (i < j && temp >= array[i])
				i++;   //从左向右找大于temp的数来填坑
			if (i < j)
				array[j--] = array[i];   //填坑array[j],形成新坑array[i]
		}
		//退出循环时,i等于j,将temp填到最后形成的坑
		array[i] = temp;
		//此时temp左边的均小于temp,temp右边的均大于temp
		//分别递归对temp左右排序
		QuickSort(array, low, i-1);
		QuickSort(array, i+1, high);
	}
}

QuickSort(array,0,array.length-1);

Base sort

    The main steps of radix sorting:

  1. First, create ten buckets to assist in sorting
  2. Sort the single digit first, and put the data in the bucket corresponding to the subscript value according to the value of the single digit
  3. After sorting, we take out the data in the bucket one by one
  4. Next, rank the tens and hundreds...
    Insert picture description here
public static void RadixSort(int[] array) {
    
    
	int[][] bucket = new int[10][array.length];   //10个基数(桶)
	int[] count = new int[10];   //记录每个桶有多少个数
	int max = array[0], num = 1, position, index;
	for(int i = 1; i < array.length; i++) {
    
       //找最大值的位数
		if (array[i] > max) {
    
    
			max = array[i];
		}
	}
	while (max != 0) {
    
    
		for (int i = 0; i < array.length; i++) {
    
    
			position = array[i] / num % 10;   //获取当前数的对应位
			bucket[position][count[position]++] = array[i];    //放入桶中
		}
		index = 0;
		for(int i = 0; i < bucket.length; i++) {
    
    
			if (count[i] != 0) {
    
    
				for(int j = 0; j < count[i]; j++) {
    
    
					array[index++]=bucket[i][j];  //放回原数组
				}
			}
			count[i] = 0;
		}
		num*=10;
		max/=10;
	}
}

Merge sort

    The main idea of ​​merge sort is divide and conquer . The main process is: (first recursion and then merge)

  1. Cut n elements from the middle and divide them into two parts. (The two parts are not necessarily equal in number)
  2. Divide step 1 into two parts, and then perform recursive decomposition. Until the number of elements in all parts is 1.
  3. Starting from the bottom layer, gradually merge the two sequenced numbers.
    Insert picture description here
public static void merge(int[] array, int low, int mid, int high, int[] temp) {
    
    
	int first = low, end1 = mid; // first是第一组的起点,end1是第一组的终点
	int second = mid + 1, end2 = high; // second是第二组的起点,end2是第二组的终点
	int index = 0; // 临时数组下标
	while (first <= end1 && second <= end2) {
    
       //将两个有序序列循环比较,填入数组temp
		if (array[first] >= array[second])
			temp[index++] = array[second++];
		else
			temp[index++] = array[first++];
	}
	while (first <= end1)     //如果比较完毕,第一组还有数剩下,则全部填入temp
		temp[index++] = array[first++];
	while (second <= end2)     //如果比较完毕,第二组还有数剩下,则全部填入temp
		temp[index++] = array[second++];
	for(int i = 0; i < index; i++)     //将排序好的数填回原数组
		array[low + i] = temp[i];
}

public static void MergeSort(int[] array, int low, int high, int[] temp) {
    
    
	if (low < high) {
    
    
		int mid = (low + high) / 2;
		MergeSort(array, low, mid, temp);
		MergeSort(array, mid +1, high, temp);
		merge(array, low, mid, high, temp);
	}
}

int[] temp=new int[array.length];
MergeSort(array,0,array.length-1);

 Heap sort

    The parent node of the node is n/2-1 , the left child node of the node is 2*n+1 , and the right child node of the node is 2*n+2 .     The final result
    adjusted to the large top pile
Insert picture description here
is 58,106,121,125,145,156,174,182,195,199.
Insert picture description here

public static void tranfer(int[] array, int index, int endIndex) {
    
    
	int temp = array[index];   //先取出当前元素
	for (int i = 2 * index + 1; i < endIndex; i = 2 * i + 1) {
    
       //从当前结点的左子结点开始
		//如果存在子节点,左子结点小于右子结点,指向右子结点
		if (i + 1 < endIndex && array[i] < array[i + 1]) {
    
    
			i++;
		}
		if (array[i] > temp) {
    
       //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)大的往上移
			array[index] = array[i];
			index = i;   //元素的位置下移
		}else {
    
    
			break;
		}
	}
	array[index] = temp;   //将temp值放到最终的位置
}

public static void HeapSort(int[] array) {
    
    
	int temp;
	for(int i = array.length / 2 - 1; i >= 0; i--) {
    
    
		//从第一个非叶子结点从下至上,从右至左调整结构
		tranfer(array, i, array.length);
	}
	//调整堆结构+交换堆顶元素与末尾元素
	for(int i = array.length - 1; i > 0; i--) {
    
    
		temp = array[0];
		array[0] = array[i];   //将堆顶元素与末尾元素进行交换
		array[i] = temp;
		tranfer(array, 0, i);   //重新对堆进行调整
	}
}

   to sum up

Sorting Algorithm Average time complexity Best time complexity Worst time complexity Space complexity Is it stable
Bubble Sort O (n 2 ) O (n) O (n 2 ) O (1) stable
Select sort O (n 2 ) O (n 2 ) O (n 2 ) O (1) Unstable
Insertion sort O (n 2 ) O (n) O (n 2 ) O (1) stable
Hill sort O (n 1.3 ) O (n) O (n 2 ) O (1) Unstable
Quick sort O(nlog2n) O(nlog2n) O (n 2 ) O(nlog2n) Unstable
Base sort O (N ∗ M) O (N ∗ M) O (N ∗ M) O(N+M) stable
Merge sort O(nlog2n) O(nlog2n) O(nlog2n) O (n) stable
Heap sort O(nlog2n) O(nlog2n) O(nlog2n) O (1) Unstable
  1. Merge sort can reduce the space complexity to O(1) through the hand-cranked algorithm, but the time complexity will increase.
  2. The time complexity of radix sorting is O(N*M), where N is the number of data and M is the number of data bits.

Guess you like

Origin blog.csdn.net/H_X_P_/article/details/106029198