设为首页 加入收藏

TOP

算法怎么就这么难---归并排序和快速排序(一)
2015-07-20 17:59:55 来源: 作者: 【 】 浏览:6
Tags:算法 怎么 这么 --- 归并 排序 快速
最近学了几天基础的数据结构的知识,越学越为自己的智商捉急了,再看看好多大牛的一些关于算法的博客,真心觉得差距是这么这么大。好了,废话不多少了,接下来我简要讲述一下两个基本的排序:归并排序和快速排序:
?
归并排序
归并排序的原理:归并排序是将一个集合分成两部分:part1和part2,分别对part1和part2进行排序(使用递归法,直到子集合的大小为1,则停止将集合拆分,此时因为子集合中只有一个元素,所以,这个子集合也就相当于已经拍好了顺序),最后将这两部分排好顺序的集合合并为一。
?
在编写代码的时候有几个注意点:
?
如何将集合分成两部分,各大小都为多少?
集合的第一部分为list.length/2;集合的第二部分为list.length-list.length/2;
?
集合的递归调用什么时候停止?
当子集合的大小为1时,则停止对集合划分,故在方法的一开始应该加上一个判断
?
If(list.length > 1){
?
};
?
代码实现:
?
public static void mergeSort(int[] list){
?
? ? ? ? if(list.length > 1){
?
? ? ? ? ? ? int[] half1 = new int[list.length/2];
?
? ? ? ? ? ? int[] half2 = new int[list.length - list.length/2];
?
? ? ? ? ? ? System.arraycopy(list, 0, half1, 0, half1.length); //将集合的前半部分复制到half1中
?
? ? ? ? ? ? mergeSort(half1);
?
? ? ? ? ? ? System.arraycopy(list, list.length/2, half2, 0, half2.length); //将集合的后半部分复制到half2中
?
? ? ? ? ? ? mergeSort(half2);
?
? ? ? ? ? ??
?
? ? ? ? ? ? int[] temp = merge(half1,half2); //将两个集合合并
?
? ? ? ? ? ? System.arraycopy(temp, 0, list, 0, temp.length);
?
? ? ? ? }
?
? ? }
?
上段代码的merge方法的作用是将两个集合合并为一个并返回。
?
代码实现:
?
private static int[] merge(int[] list1, int[] list2){
?
? ? ? ? int[] temp = new int[list1.length + list2.length];
?
? ? ? ? int currentPosition1 = 0; //遍历list1时使用的下标变量
?
? ? ? ? int currentPosition2 = 0; //遍历list2时使用的下标变量
?
? ? ? ? int currentPositionTemp = 0; //合并两个list时使用的下标变量
?
?
?
? ? ? ? //将两个集合中的元素copy到临时变量中
?
while(currentPosition1 < list1.length && currentPosition2 < list2.length){ ? ? ? ? ? ? if(list1[currentPosition1] < list2[currentPosition2]){ //将小的元素放到前面。
?
? ? ? ? ? ? ? ? temp[currentPositionTemp++] = list1[currentPosition1++];
?
? ? ? ? ? ? }else
?
? ? ? ? ? ? {
?
? ? ? ? ? ? ? ? temp[currentPositionTemp++] = list2[currentPosition2++];
?
? ? ? ? ? ? }
?
? ? ? ? }
?
? ? ? ? //运行到此处时,list1和list2中的至少其中一个list已经全部复制到临时集合中,但有可能list1中元素的数量小于list2中元素
?
//的数量,因此,需要将list1或者list2中的剩余的数据复制到临时集合中。
?
? ? ? ? while(currentPosition1 < list1.length){
?
? ? ? ? ? ? temp[currentPositionTemp++] = list1[currentPosition1++];
?
? ? ? ? }
?
? ? ? ? while(currentPosition2 < list2.length){
?
? ? ? ? ? ? temp[currentPositionTemp++] = list2[currentPosition2++];
?
? ? ? ? }
?
? ? ? ? return temp;
?
? ? }
?
?
?
测试代码:
?
public static void main(String[] args) {
?
? ? ? ? // TODO Auto-generated method stub
?
? ? ? ? int[] list = {1,29,1,2,90,1,0};
?
? ? ? ? mergeSort(list);
?
? ? ? ? for(int temp : list){
?
? ? ? ? ? ? System.out.print(temp + " ");
?
? ? ? ? }
?
? ? ? ? System.out.println();
?
? ? }
?
运行结果:
?
?
?
?
?
?
?
快速排序
快速排序的原理:快速排序在数组中选择一个称为主元(pivot)的元素将数组分成两个部分,使得第一部分的所有元素小于或等于主元(pivot),而第二部分的所有元素均大于主元(pivot)。然后对第一部分递归得应用快速排序算法,然后对第二部分递归得应用快速排序算法。
?
Pivot的英文意思为中心点,所以,快速排序可以理解为找中心点,然后根据中心点,将数组分成两部分,一部分小于或等于中心点,另一部分大于中心点,然后按照此方法对两个部分分别执行,最后就将数组排好了顺序。
?
为了简单起见,接下来我的代码实现中,将数组的第一个元素作为中心点(pivot)。
?
代码如下:
?
说明:此段代码的功能是根据集合的第一个元素作为中心点(pivot)将集合分成两个部分,返回中间点pivot的下标
?
private static int partition(int[] list, int first, int last){
?
//参数first和last用于指定,将集合的哪一段按照pivot分成两部分。
?
? ? ? ? int pivot = list[first]; //取第一个元素作为集合的中心点(pivot)
?
? ? ? ? int low = first + 1;
?
? ? ? ? int high = last;
?
? ? ? ??
?
? ? ? ? while(high > low){
?
//找到从前向后数第一个大于pivot的元素,然后找到从后向前数第一个小于pivot的元素,将他们两个互换
?
? ? ? ? ? ? while
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 1180 诡异的楼梯 (DFS) 下一篇getWidth和getMeasuredWidth在何..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: