常见排序算法原理及java实现

最近整理了几种常见排序算法,基于java代码实现,都只是点干货,没有过多原理分析,后期会持续更新

/**
	 * 
	 * 冒泡排序 @author :manzi Create Date : 2019年4月29日 下午6:55:20
	 * 
	 * 原理:比较两个相邻的元素,将值大的元素交换至右端。
	 * 
	 * 1思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。
	 * 2即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。
	 * 3然后比较第2个数和第3个数,将小数放前,大数放后,
	 * 4如此继续,直至比较最后两个数,将小数放前,大数放后。
	 * 5重复第一趟步骤,直至全部排序完成。
	 */
	public static void bubbleSort(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = i + 1; j < arr.length; j++) {
				if (arr[i] > arr[j]) {
					int temp = arr[i];
					arr[i] = arr[j];
					arr[j] = temp;
				}
			}

		}
	}

	/**
	 * 
	 * 插入排序 @author :manzi Create Date : 2019年4月29日 下午6:55:46
	 * 
	 * 原理:将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,
	 * 		算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
	 * 
	 * 1从第一个元素开始,该元素可以认为已经被排序 
	 * 2取出下一个元素,在已经排序的元素序列中从后向前扫描
	 * 3如果该元素(已排序)大于新元素,将该元素移到下一位置 
	 * 4重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 
	 * 5将新元素插入到该位置后
	 * 6重复步骤2~5
	 * 
	 */
	public static void insertSortFor(int[] arr) {
		for (int i = 0; i < arr.length - 1; i++) {
			for (int j = i + 1; j > 0; j--) {
				if (arr[j] < arr[j - 1]) {
					int temp = arr[j];
					arr[j] = arr[j - 1];
					arr[j - 1] = temp;
				} else {
					break;
				}
			}
		}
	}

	public static void insertSortWhile(int[] arr) {
		for (int i = 1; i < arr.length; i++) {
			int temp = arr[i];
			while (i > 0 && temp < arr[i - 1]  ) {
				arr[i] = arr[i - 1];
				i--;
			}
			arr[i] = temp;
		}
	}

	/**
	 * 
	 * 选择排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30
	 *
	 * 原理:选择排序,从头至尾扫描序列,找出最小的一个元素,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,最终得到一个有序序列
	 * 
	 * 1.将序列分为两段,有序前列[0,r)和无序后列[r,n-1]
	 * 2.在无序后列中查找最大元素s=A[m],记住其所在位置
	 * 3.将无序后列中的最大元素与无序前列的首位元素进行交换
	 * 4.循环停止标识:无序后列只剩余最后一个元素
	 */
	public static void selectSort(int[] arr) {
		for (int i = 0; i < arr.length; i++) {
			int k = i;
			for (int j = i; j < arr.length; j++) {
				if (arr[j] < arr[k]) {
					k = j;
				}
			}
			if (k != i) {
				int temp = arr[i];
				arr[i] = arr[k];
				arr[k] = temp;
			}
		}
	}

	/**
	 * 
	 * 快速排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30
	 * 
	 * 原理:底层是冒泡排序。它是通过一趟排序,将一组数据分为两部分,
	 * 其中一部分要比另一部分的所有数据都要小,然后再用此方法分别进行快速排序,以达到一组数据的有序排序
	 * 
	 * 1.先从数列中取出一个数作为基准数。
	 * 2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
	 * 3.再对左右区间重复第二步,直到各区间只有一个数。
	 * 
	 * 挖坑填数+分治法+递归
	 */
	public static void quickSort(int[] arr, int left, int right) {
		if (left >= right) {
			return;
		}
		int i = left;
		int j = right;
		int dest = arr[i];
		while (i < j) {
			while (i < j && dest <= arr[j]) {
				j--;
			}
			if (i < j) {
				arr[i++] = arr[j];
			}
			while (i < j && dest > arr[i]) {
				i++;
			}
			if (i < j) {
				arr[j--] = arr[i];
			}
		}
		arr[i] = dest;
		quickSort(arr, left, i - 1);
		quickSort(arr, i + 1, right);

	}



	/**
	 * 
	 * 归并排序 @author :manzi Create Date : 2019年4月29日 下午6:56:30
	 * 
	 * 原理:排序一个数组,把数组从中间分为两部分,然后对前后两部分进行分别排序。最后把排序好的两部分都合并在一起,在合并的时候也会进行排序
	 * 
	 * 1申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 
	 * 2设定两个指针,最初位置分别为两个已经排序序列的起始位置
	 * 3比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 
	 * 4重复步骤3直到某一指针达到序列尾
	 * 5将另一序列剩下的所有元素直接复制到合并序列尾
	 * 6将临时数组中元素替换原数组元素
	 */
	public static void mergeSort(int[] arr, int low, int high) {
		int middle = (high + low) / 2;
		if (low < high) {
			mergeSort(arr, low, middle);
			mergeSort(arr, middle + 1, high);
			mergeSort(arr, low, middle, high);

		}
	}

	public static void mergeSort(int[] arr, int low, int middle, int high) {
		int i = low;
		int j = middle + 1;
		int k = 0;
		int temp[] = new int[high - low + 1];
		while (i <= middle && j <= high) {
			if (arr[i] < arr[j]) {
				temp[k++] = arr[i++];
			} else {
				temp[k++] = arr[j++];
			}
		}
		while (i <= middle) {
			temp[k++] = arr[i++];
		}
		while (j <= high) {
			temp[k++] = arr[j++];
		}
		while (high >= low) {
			arr[high--] = temp[--k];
		}
	}

猜你喜欢

转载自www.cnblogs.com/zmanzi/p/10803443.html