Java排序:冒泡排序、快速排序、堆排序

冒泡排序:
 一趟排序:将第一个记录和第二个记录进行比较,如果第一个比第二个大就两个记录交换,直到第n-1个记录和第n个记录比较为止。
  之后的排序对前n-1个记录进行同样操作。

  时间复杂度为O(n^2)

每一趟排序就是把最大的数放到最后面。


快速排序:
 一趟交换:设两个指针low和high,设枢轴记录为pivotkey,从high所指的位置向前搜索找到第一个关键词小于pivotkey的记录和枢轴记录相互交换,
 从low所值位置向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录交换。直到low=high。

 时间复杂度为O(nlogn),当初始记录为有序或基本有序时时间复杂度蜕变成冒泡排序,时间复杂度为O(n)

把数组切分成两个部分,一边比pivotkey大,一边比pivotkey小。用递归把两个部分再分别排序。

堆排序:
* 在输出堆顶的最小值之后,使得剩余n-1个元素的序列重新建成一个堆,则达到n个元素中的此校元素。反复执行。
* 在最坏的情况下时间复杂度也为O(nlogn)
* 对记录数较少的文件不值得体长,对n较大的文件还是很有效的

构建一个大顶堆
* 先选一个关键字为最大的记录并于序列中最后一个记录交换,然后对序列中前n-1记录进行筛选,重新调整为一个大顶堆
* 对于使用数组表示二叉树还需要再进行复习

/**
	 * 冒泡排序
	 * 一趟排序:将第一个记录和第二个记录进行比较,如果第一个比第二个大就两个记录交换,直到第n-1个记录和第n个记录比较为止。
	 * 之后的排序对前n-1个记录进行同样操作。
	 * 时间复杂度为O(n^2)
	 * @param nums
	 */
	public static void BubbleSrot(int[] nums) {
		//控制排序的趟数
		for (int i = 0; i < nums.length - 1; i++) {
			//控制每一趟排序多少次
			for (int j = 0; j < nums.length - 1 - i; j++) {
				if (nums[j] > nums[j + 1]) {
					int temp = nums[j + 1];
					nums[j + 1] = nums[j];
					nums[j] = temp;
				}
			}
		}
	}
	/**
	 * 快速排序
	 * 一趟交换:设两个指针low和high,设枢轴记录为pivotkey,从high所指的位置向前搜索找到第一个关键词小于pivotkey的记录和枢轴记录相互交换,
	 * 从low所值位置向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录交换。直到low=high。
	 * 时间复杂度为O(nlogn),当初始记录为有序或基本有序时时间复杂度蜕变成冒泡排序,时间复杂度为O(n)
	 * @param nums
	 */
	public static void QuickSort(int[] nums) {
		QuickSort(nums, 0, nums.length - 1);
	}

	private static void QuickSort(int[] nums, int low, int high) {
		int begin = low, end = high;
		// 一趟交换
		// 将数组中第一个做为枢轴记录
		int pivotkey = nums[begin];
		while (begin < end) {
			// 比枢轴记录小的数值移动到低端
			while (begin < end && nums[end] >= pivotkey) {
				--end;
			}
			nums[begin] = nums[end];
			// 比枢轴记录大的数值移动到高端
			while (begin < end && nums[begin] <= pivotkey) {
				++begin;
			}
			nums[end] = nums[begin];
		}
		// 将枢轴记录补充到low的位置上
		nums[begin] = pivotkey;
		// 一趟交换结束

		// 递归
		// 递归排序左边
		if (low < end) {
			QuickSort(nums, low, end - 1);
		}
		// 递归排序右边
		if (begin < high) {
			QuickSort(nums, begin + 1, high);
		}
	}
	/**
	 * 堆排序
	 * 在输出堆顶的最小值之后,使得剩余n-1个元素的序列重新建成一个堆,则达到n个元素中的此校元素。反复执行。
	 * 在最坏的情况下时间复杂度也为O(nlogn)
	 * 对记录数较少的文件不值得体长,对n较大的文件还是很有效的
	 * @param nums
	 */
	public static void HeapSort(int[] nums){
		for(int i = nums.length/2;i>=0;--i){
			HeapAdjust(nums,i,nums.length);
		}
		for(int i = nums.length-1;i>=0;--i){
			int temp = nums[i];
			nums[i] = nums[0];
			nums[0] = temp;
			HeapAdjust(nums,0,i-1);
		}
	}
	/**
	 * 构建一个大顶堆
	 * 先选一个关键字为最大的记录并于序列中最后一个记录交换,然后对序列中前n-1记录进行筛选,重新调整为一个大顶堆
	 * 对于使用数组表示二叉树还需要再进行复习
	 * @param nums
	 * @param s
	 * @param len
	 */
	private static void HeapAdjust(int[] nums ,int s ,int len){
		System.out.println(Arrays.toString(nums));
		int r = nums[s];
		for(int j = 2 * s;j<len;j*=2){
			if(j<len&&nums[j]<nums[j+1]){
				++j;
			}
			if(r>=nums[j]) break;
			nums[s] = nums[j];
			s = j;
		}
		nums[s]=r;
	}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章