关于常用排序算法的一个总结

Posted beststrive

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于常用排序算法的一个总结相关的知识,希望对你有一定的参考价值。

  前段时间被人问到排序算法,今天特此总结一下,冒泡,选择,快排,归并,插入这五种排序算法。

  1.选择排序

  选择排序是整体对比,每次选出你最需要的那个值,比如以下代码,首先选出最小的值,从小实现从小到大排序,外循环一次,内部循环记录下最小的坐标,只发生一次交换,它是一种稳定的排序算法,时间复杂度为o(n2),核心代码如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
		int arraylength = numberArray.length;
		int temp = 0;
		for (int i = 0; i < arraylength - 1; i++) {
			int k = i;
			for (int j = i + 1; j < arraylength; j++) {
				if (numberArray[k] > numberArray[j]) {
					k = j;
				}
			}

			if (i != k) {
				temp = numberArray[i];
				numberArray[i] = numberArray[k];
				numberArray[k] = temp;
			}
		}
		System.out.println(Arrays.toString(numberArray));

  2.冒泡排序

  冒泡排序的核心思路是相邻元素进行对比,把大的数往后移,外循环一次,内部循环可能会发生很多次交换,它是一种稳定的算法,时间复杂度为o(n2),核心代码如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
        int arraylength = numberArray.length;
        int temp = 0;
        for (int i = 0; i < arraylength - 1; i++) {
            for (int j = i + 1; j < arraylength; j++) {
                if (numberArray[i] > numberArray[j]) {
                    temp = numberArray[i];
                    numberArray[i] = numberArray[j];
                    numberArray[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(numberArray));

 

  3.插入排序

  插入排序通过默认一个正确的位置,然后寻找插入位置,有点像我们完斗地主时,会把连牌挨着大小放着,它也是一种稳定的排序算法,时间复杂度为o(n2),核心代码如下:

int[] numberArray = { 22, 32, 12, 1, 5, 66 };
		for (int i = 1; i < numberArray.length; i++) {
			////把j看作一个游标
			int j = i;
			int target = numberArray[i];
			while (j > 0 && target < numberArray[j - 1]) {
				//// 说明有更大的,往后移
				numberArray[j] = numberArray[j - 1];
				j--;
			}

			numberArray[j] = target;
		}
		System.out.println(Arrays.toString(numberArray));

  4.快速排序

  快速排序的核心是冒泡+二分+递归分治,实际应用中算是最好的排序算法了,但它是一种不稳定的排序算法,平均时间复杂度为o(nlgn),最坏的情况是o(n2),它和冒泡算法的区别是同时查找大的数和小的数,核心代码如下:

  

public static void main(String[] args) {
		try {
			int[] numberArray = new int[] { 4, 3, 6, 1, 2, 5 };
			recursionSort(numberArray, 0, numberArray.length - 1);
			System.out.println(Arrays.toString(numberArray));
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	private static void recursionSort(int[] numberArray, int low, int high) {
		if (low < high) {
			int basevalueIndex = partitionGroup(numberArray, low, high);
			////左区间递归
			recursionSort(numberArray, low, basevalueIndex - 1);
			////右区间递归
			recursionSort(numberArray, basevalueIndex + 1, high);
		}
	}

	private static int partitionGroup(int[] numberArray, int low, int high) {
		int basevalue = numberArray[low];
		while (low < high) {
			//// 先从右向左
			while (low < high && numberArray[high] >= basevalue) {
				--high;
			}
			//// 交换比基准值小的到左边
			numberArray[low] = numberArray[high];
			while (low < high && numberArray[low] <= basevalue) {
				++low;
			}

			//// 交互比基准值大的到右边
			numberArray[high] = numberArray[low];
		}

		//// 扫描完成,左右下标,即low=high
		numberArray[low] = basevalue;

		//// 返回基准值的下标
		return low;
	}

 

  5.归并排序

 

   理论上归并排序的效率应该高于快速排序,但是由于赋值次数较多以及分配临时数组等,所以和快排的效率应该不相上下。它的思路就是把原始数组序列不断两两分块,直到每一个块只剩下一个元素,然后利用递归的原理合并即可,它是一种稳定的排序算法,时间复杂度为o(n2),核心代码如下:

  

public static void main(String[] args) {
		try {
			int[] numberArray = new int[] { 4, 3, 6, 1, 2, 5 };
			partition(numberArray, 0, numberArray.length - 1);
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
	}

	public static void partition(int[] a, int low, int high) {
		int mid = (low + high) / 2;
		if (low < high) {
			// 左边
			partition(a, low, mid);
			// 右边
			partition(a, mid + 1, high);
			// 左右归并
			merge(a, low, mid, high);
			System.out.println(Arrays.toString(a));
		}

	}

	public static void merge(int[] numberArray, int low, int mid, int high) {
		int[] temp = new int[high - low + 1];
		//// 左指针
		int i = low;
		// 右指针
		int j = mid + 1;
		int k = 0;
		// 把较小的数先移到新数组中
		while (i <= mid && j <= high) {
			if (numberArray[i] < numberArray[j]) {
				temp[k++] = numberArray[i++];
			} else {
				temp[k++] = numberArray[j++];
			}
		}
		// 把左边剩余的数移入数组
		while (i <= mid) {
			temp[k++] = numberArray[i++];
		}
		// 把右边边剩余的数移入数组
		while (j <= high) {
			temp[k++] = numberArray[j++];
		}
		// 把新数组中的数覆盖nums数组
		for (int k2 = 0; k2 < temp.length; k2++) {
			numberArray[k2 + low] = temp[k2];
		}
	}

  

  

以上是关于关于常用排序算法的一个总结的主要内容,如果未能解决你的问题,请参考以下文章

常用算法代码模板总结

js 常用的比较排序算法总结

Java排序算法 - 堆排序的代码

常用排序算法总结

常用排序方法总结

常用排序算法总结