用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字
云代码 - java代码库

java快速排序算法

2012-08-26 作者: 神马举报

[java]代码库

/**
 * 快速排序
 * 
 * 在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为X),用此基准将当前无序区划分为左右两个较小的无序区:
 * R[1..I-1]和R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,
 * 而基准X则位于最终排序的位置上,即R[1..I-1]≤ X.Key≤R[I+1..H](1≤I≤H),当R[1..I-1]和R[I+1..H]均非空时,
 * 分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。
 */

public class QuickSort {

	/**
	 * 排序算法的实现,对数组中指定的元素进行排序
	 * 
	 * @param array
	 *            待排序的数组
	 * @param from
	 *            从哪里开始排序
	 * @param end
	 *            排到哪里
	 * @param c
	 *            比较器
	 */
	// 定义了一个这样的公有方法sort,在这个方法体里面执行私有方法quckSort(这种方式值得借鉴)。
	public void sort(Integer[] array, int from, int end) {
		quickSort(array, from, end);
	}

	/**
	 * 递归快速排序实现
	 * 
	 * @param array
	 *            待排序数组
	 * @param low
	 *            低指针
	 * @param high
	 *            高指针
	 * @param c
	 *            比较器
	 */
	private void quickSort(Integer[] array, int low, int high) {
		/*
		 * 如果分区中的低指针小于高指针时循环;如果low=higth说明数组只有一个元素,无需再处理; 如果low >
		 * higth,则说明上次枢纽元素的位置pivot就是low或者是higth,此种情况 下分区不存,也不需处理
		 */
		if (low < high) {
			// 对分区进行排序整理

			// int pivot = partition1(array, low, high);
			int pivot = partition2(array, low, high);
			// int pivot = partition3(array, low, high);

			/*
			 * 以pivot为边界,把数组分成三部分[low, pivot - 1]、[pivot]、[pivot + 1, high]
			 * 其中[pivot]为枢纽元素,不需处理,再对[low, pivot - 1]与[pivot + 1, high]
			 * 各自进行分区排序整理与进一步分区
			 */
			quickSort(array, low, pivot - 1);
			quickSort(array, pivot + 1, high);
		}

	}

	/**
	 * 实现一
	 * 
	 * @param array
	 *            待排序数组
	 * @param low
	 *            低指针
	 * @param high
	 *            高指针
	 * @param c
	 *            比较器
	 * @return int 调整后中枢位置
	 */
	private int partition1(Integer[] array, int low, int high) {
		Integer pivotElem = array[low];// 以第一个元素为中枢元素
		// 从前向后依次指向比中枢元素小的元素,刚开始时指向中枢,也是小于与大小中枢的元素的分界点
		int border = low;

		/*
		 * 在中枢元素后面的元素中查找小于中枢元素的所有元素,并依次从第二个位置从前往后存放
		 * 注,这里最好使用i来移动,如果直接移动low的话,最后不知道数组的边界了,但后面需要 知道数组的边界
		 */
		for (int i = low + 1; i <= high; i++) {
			// 如果找到一个比中枢元素小的元素
			if ((array[i].compareTo(pivotElem)) < 0) {
				swap(array, ++border, i);// border前移,表示有小于中枢元素的元素
			}
		}
		/*
		 * 如果border没有移动时说明说明后面的元素都比中枢元素要大,border与low相等,此时是
		 * 同一位置交换,是否交换都没关系;当border移到了high时说明所有元素都小于中枢元素,此
		 * 时将中枢元素与最后一个元素交换即可,即low与high进行交换,大的中枢元素移到了 序列最 后;如果 low <minIndex<
		 * high,表 明中枢后面的元素前部分小于中枢元素,而后部分大于
		 * 中枢元素,此时中枢元素与前部分数组中最后一个小于它的元素交换位置,使得中枢元素放置在 正确的位置
		 */
		swap(array, border, low);
		return border;
	}

	/**
	 * 实现二
	 * 
	 * @param array
	 *            待排序数组
	 * @param low
	 *            待排序区低指针
	 * @param high
	 *            待排序区高指针
	 * @param c
	 *            比较器
	 * @return int 调整后中枢位置
	 */
	private int partition2(Integer[] array, int low, int high) {
		int pivot = low;// 中枢元素位置,我们以第一个元素为中枢元素
		// 退出条件这里只可能是 low = high
		while (true) {
			if (pivot != high) {// 如果中枢元素在低指针位置时,我们移动高指针
				// 如果高指针元素小于中枢元素时,则与中枢元素交换
				if ((array[high].compareTo(array[pivot])) < 0) {
					swap(array, high, pivot);
					// 交换后中枢元素在高指针位置了
					pivot = high;
				} else {// 如果未找到小于中枢元素,则高指针前移继续找
					high--;
				}
			} else {// 否则中枢元素在高指针位置
				// 如果低指针元素大于中枢元素时,则与中枢元素交换
				if ((array[low].compareTo(array[pivot])) > 0) {
					swap(array, low, pivot);
					// 交换后中枢元素在低指针位置了
					pivot = low;
				} else {// 如果未找到大于中枢元素,则低指针后移继续找
					low++;
				}
			}
			if (low == high) {
				break;
			}
		}
		// 返回中枢元素所在位置,以便下次分区
		return pivot;
	}

	/**
	 * 实现三
	 * 
	 * @param array
	 *            待排序数组
	 * @param low
	 *            待排序区低指针
	 * @param high
	 *            待排序区高指针
	 * @param c
	 *            比较器
	 * @return int 调整后中枢位置
	 */
	private int partition3(Integer[] array, int low, int high) {
		int pivot = low;// 中枢元素位置,我们以第一个元素为中枢元素
		low++;
		// ----调整高低指针所指向的元素顺序,把小于中枢元素的移到前部分,大于中枢元素的移到后面部分
		// 退出条件这里只可能是 low = high

		while (true) {
			// 如果高指针未超出低指针
			while (low < high) {
				// 如果低指针指向的元素大于或等于中枢元素时表示找到了,退出,注:等于时也要后移
				if ((array[low].compareTo(array[pivot])) >= 0) {
					break;
				} else {// 如果低指针指向的元素小于中枢元素时继续找
					low++;
				}
			}

			while (high > low) {
				// 如果高指针指向的元素小于中枢元素时表示找到,退出
				if ((array[high].compareTo(array[pivot])) < 0) {
					break;
				} else {// 如果高指针指向的元素大于中枢元素时继续找
					high--;
				}
			}
			// 退出上面循环时 low = high
			if (low == high) {
				break;
			}

			swap(array, low, high);
		}

		// ----高低指针所指向的元素排序完成后,还得要把中枢元素放到适当的位置
		if ((array[pivot].compareTo(array[low])) > 0) {
			// 如果退出循环时中枢元素大于了低指针或高指针元素时,中枢元素需与low元素交换
			swap(array, low, pivot);
			pivot = low;
		} else if ((array[pivot].compareTo(array[low])) <= 0) {
			swap(array, low - 1, pivot);
			pivot = low - 1;
		}

		// 返回中枢元素所在位置,以便下次分区
		return pivot;
	}

	/**
	 * 交换数组中的两个元素的位置
	 * 
	 * @param array
	 *            待交换的数组
	 * @param i
	 *            第一个元素
	 * @param j
	 *            第二个元素
	 */
	public void swap(Integer[] array, int i, int j) {
		if (i != j) {// 只有不是同一位置时才需交换
			Integer tmp = array[i];
			array[i] = array[j];
			array[j] = tmp;
		}
	}

	/**
	 * 测试
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		Integer[] intgArr = { 5, 9, 1, 4, 2, 6, 3, 8, 0, 7 };
		QuickSort quicksort = new QuickSort();
		quicksort.sort(intgArr, 0, intgArr.length - 1);
		for (Integer intObj : intgArr) {
			System.out.print(intObj + " ");
		}
	}
}


网友评论    (发表评论)


发表评论:

评论须知:

  • 1、评论每次加2分,每天上限为30;
  • 2、请文明用语,共同创建干净的技术交流环境;
  • 3、若被发现提交非法信息,评论将会被删除,并且给予扣分处理,严重者给予封号处理;
  • 4、请勿发布广告信息或其他无关评论,否则将会删除评论并扣分,严重者给予封号处理。


扫码下载

加载中,请稍后...

输入口令后可复制整站源码

加载中,请稍后...