排序算法比较.docx
- 文档编号:6475963
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:19
- 大小:27.38KB
排序算法比较.docx
《排序算法比较.docx》由会员分享,可在线阅读,更多相关《排序算法比较.docx(19页珍藏版)》请在冰豆网上搜索。
排序算法比较
交换排序
冒泡排序
将最后一个元素与倒数第二个元素对比,如果最后一个元素比倒数第二个小,则交换两个元素的位置,再用倒数第二个元素与倒数第三个元数对比,直到比到第一个元素,这样经过第一趟排序后得到第一个最小元素。
如此反复几过N(N=length-1)次后可得到排序结果。
Java代码
1packagesort;
2
3importjava.util.Comparator;
4
5/**
6*冒泡排序算法
7*@authorjzj
8*@date2009-12-9
9*
10*@param
11*/
12publicclassBubbleSort
13
14/**
15*排序算法的实现,对数组中指定的元素进行排序
16*@paramarray待排序的数组
17*@paramfrom从哪里开始排序
18*@paramend排到哪里
19*@paramc比较器
20*/
21publicvoidsort(E[]array,intfrom,intend,Comparator
22//需array.length-1轮比较
23for(intk=1;k 24//每轮循环中从最后一个元素开始向前起泡,直到i=k止,即i等于轮次止 25for(inti=end-from;i>=k;i--){ 26//按照一种规则(后面元素不能小于前面元素)排序 27if(pare(array[i],array[i-1])<0){ 28//如果后面元素小于了(当然是大于还是小于要看比较器实现了)前面的元素,则前后交换 29swap(array,i,i-1); 30} 31} 32} 33} 34 35/** 36*测试 37*@paramargs 38*/ 39publicstaticvoidmain(String[]args){ 40Integer[]intgArr={7,2,4,3,12,1,9,6,8,5,11,10}; 41BubbleSort 42BubbleSort.testSort(sort,intgArr); 43BubbleSort.testSort(sort,null); 44} 45} 快速排序 快速排序采用了分治法的思想,把大的问题分解为同类型的小问题。 一般分如下步骤: 1)选择一个中枢元素(有很多选法,我的实现里使用第一个元素为中枢的简单方法) 2)以该中枢元素为基准点,将小于中枢的元素放在中枢后集合的前部分,比它大的在集合后部分,待集合基本排序完成后(此时前部分元素小于后部分元素),把中枢元素放在合适的位置。 3)根据中枢元素最后确定的位置,把数组分成三部分,左边的,右边的,枢纽元素自己,对左边的,右边的分别递归调用快速排序算法即可。 这里的重点与难点在于第二步,实现的方式有很多种,我这里实现了三种。 第一种实现(partition1方法): 以第一个元素为中枢元素,在中枢元素后面集合中从前往后寻找第一个比中枢元素小的元素,并与第一个元素交换,然后从剩余的元素中寻找第二个比中枢元素小的元素,并与第二位元素交换,这样直到所有小于中枢元素找完为止,并记下最后一次放置小于中枢的元素位置minIndex(即小于中枢与大于中枢的分界),并将中枢元素与minIndex位置元素互换,然后对中枢元素两边的序列进行同样的操作。 此种实现最为简洁,处理过程中不需要把中枢元素移来移去,只是在其它元素完成基本排序后(前部分小于后部分元素)再把中枢元素放置到适当的位置 第二种实现(partition2方法): 以第一个元素为中枢元素,刚开始时使用低指针指向中枢元素。 当中枢元素在低指针位置时,此时我们判断高指针指向的元素是否小于中枢元素,如果大于中枢元素则高指针继续向头移动,如果小于则与中枢元素交换,此时中枢元素被移到了高指针位置;当中枢元素在高指针位置时,我们此时判断低指针指向的元素是否大于中枢元素,如果小于中枢元素则低指针继续向尾移动,如果大于则与中枢元素交换,此时中枢元素又回到了低指针位置;这时是拿高还是低指针所指向的元素与中枢比较时根据前面逻辑来处理,直到高低指针指向同一位置则完成一轮排序,然后再对中枢元素两边的序列进行同样的操作直到排序完成 此种实现逻辑比较好理解,中枢元素的永远在低指针或指针所指向的位置,每次找到需处理的元素后,要与中枢交换,中枢就像皮球一样从这里踢到那里,又从那里踢到这里。 但此种实现会频繁地交换中枢元素,性能可能不如第一种 第三种实现(partition3方法): 此种方式与前两种方式不太一样,同时移动高低指针,低指针向尾找出大于等于中枢的元素,而高向头找出小于中枢的元素,待两者都找出后交换高低指针所指向的元素,直到高低指针指向同一位置止,然后比较中枢与高低指针所指向的元素大小,如果中枢元素大,则直接与高低指针元素交换,如果中枢元素小于等于高低指针元素,则中枢元素与高低指针前一元素交换,完成一轮比较,然后再对中枢元素两边的序列进行同样的操作直到排序完成 此种方式有点难度,在移动元素时要注意的是: 与中枢相等的元素也要向集合后部移动,不然的话如[3,3,0,3,3]第一轮排序结果不准确,虽然最后结果正确。 当中枢后面的元素集合移动完成后,还得要把中枢元素放置在集合中的合适位置,这就需要找准集合中前部分与后部分的边界,最后只能把中枢元素与最后一个小于中枢的元素进位置互换。 但此种实现方式与第一种有点像,也不需要把中枢元素调来调去的,而是待后面集合排序完成后将中枢放入适当位置 Java代码 46packagesort; 47 48importjava.util.Arrays; 49importjava.util.Comparator; 50 51/** 52*快速排序算法 53*@authorjzj 54*@date2009-12-9 55* 56*@param 57*/ 58publicclassQuickSort 59 60/** 61*排序算法的实现,对数组中指定的元素进行排序 62*@paramarray待排序的数组 63*@paramfrom从哪里开始排序 64*@paramend排到哪里 65*@paramc比较器 66*/ 67publicvoidsort(E[]array,intfrom,intend,Comparator 68quickSort(array,from,end,c); 69} 70 71/** 72*递归快速排序实现 73*@paramarray待排序数组 74*@paramlow低指针 75*@paramhigh高指针 76*@paramc比较器 77*/ 78privatevoidquickSort(E[]array,intlow,inthigh,Comparator 79/* 80*如果分区中的低指针小于高指针时循环;如果low=higth说明数组只有一个元素,无需再处理; 81*如果low>higth,则说明上次枢纽元素的位置pivot就是low或者是higth,此种情况 82*下分区不存,也不需处理 83*/ 84if(low 85//对分区进行排序整理 86intpivot=partition1(array,low,high,c); 87/* 88*以pivot为边界,把数组分成三部分[low,pivot-1]、[pivot]、[pivot+1,high] 89*其中[pivot]为枢纽元素,不需处理,再对[low,pivot-1]与[pivot+1,high] 90*各自进行分区排序整理与进一步分区 91*/ 92quickSort(array,low,pivot-1,c); 93quickSort(array,pivot+1,high,c); 94} 95 96} 97 98/** 99*实现一 100* 101*@paramarray待排序数组 102*@paramlow低指针 103*@paramhigh高指针 104*@paramc比较器 105*@returnint调整后中枢位置 106*/ 107privateintpartition1(E[]array,intlow,inthigh,Comparator 108EpivotElem=array[low];//以第一个元素为中枢元素 109//从前向后依次指向比中枢元素小的元素,刚开始时指向中枢,也是小于与大小中枢的元素的分界点 110intborder=low; 111 112/* 113*在中枢元素后面的元素中查找小于中枢元素的所有元素,并依次从第二个位置从前往后存放 114*注,这里最好使用i来移动,如果直接移动low的话,最后不知道数组的边界了,但后面需要 115*知道数组的边界 116*/ 117for(inti=low+1;i<=high;i++){ 118//如果找到一个比中枢元素小的元素 119if(pare(array[i],pivotElem)<0){ 120swap(array,++border,i);//border前移,表示有小于中枢元素的元素 121} 122} 123/* 124*如果border没有移动时说明说明后面的元素都比中枢元素要大,border与low相等,此时是 125*同一位置交换,是否交换都没关系;当border移到了high时说明所有元素都小于中枢元素,此 126*时将中枢元素与最后一个元素交换即可,即low与high进行交换,大的中枢元素移到了序列最 127*后;如果low 128*中枢元素,此时中枢元素与前部分数组中最后一个小于它的元素交换位置,使得中枢元素放置在 129*正确的位置 130*/ 131swap(array,border,low); 132returnborder; 133} 134 135/** 136*实现二 137* 138*@paramarray待排序数组 139*@paramlow待排序区低指针 140*@paramhigh待排序区高指针 141*@paramc比较器 142*@returnint调整后中枢位置 143*/ 144privateintpartition2(E[]array,intlow,inthigh,Comparator 145intpivot=low;//中枢元素位置,我们以第一个元素为中枢元素 146//退出条件这里只可能是low=high 147while(true){ 148if(pivot! =high){//如果中枢元素在低指针位置时,我们移动高指针 149//如果高指针元素小于中枢元素时,则与中枢元素交换 150if(pare(array[high],array[pivot])<0){ 151swap(array,high,pivot); 152//交换后中枢元素在高指针位置了 153pivot=high; 154}else{//如果未找到小于中枢元素,则高指针前移继续找 155high--; 156} 157}else{//否则中枢元素在高指针位置 158//如果低指针元素大于中枢元素时,则与中枢元素交换 159if(pare(array[low],array[pivot])>0){ 160swap(array,low,pivot); 161//交换后中枢元素在低指针位置了 162pivot=low; 163}else{//如果未找到大于中枢元素,则低指针后移继续找 164low++; 165} 166} 167if(low==high){ 168break; 169} 170} 171//返回中枢元素所在位置,以便下次分区 172returnpivot; 173} 174 175/** 176*实现三 177* 178*@paramarray待排序数组 179*@paramlow待排序区低指针 180*@paramhigh待排序区高指针 181*@paramc比较器 182*@returnint调整后中枢位置 183*/ 184privateintpartition3(E[]array,intlow,inthigh,Comparator 185intpivot=low;//中枢元素位置,我们以第一个元素为中枢元素 186low++; 187//----调整高低指针所指向的元素顺序,把小于中枢元素的移到前部分,大于中枢元素的移到后面部分 188//退出条件这里只可能是low=high 189 190while(true){ 191//如果高指针未超出低指针 192while(low 193//如果低指针指向的元素大于或等于中枢元素时表示找到了,退出,注: 等于时也要后移 194if(pare(array[low],array[pivot])>=0){ 195break; 196}else{//如果低指针指向的元素小于中枢元素时继续找 197low++; 198} 199} 200 201while(high>low){ 202//如果高指针指向的元素小于中枢元素时表示找到,退出 203if(pare(array[high],array[pivot])<0){ 204break; 205}else{//如果高指针指向的元素大于中枢元素时继续找 206high--; 207} 208} 209//退出上面循环时low=high 210if(low==high){ 211break; 212} 213 214swap(array,low,high); 215} 216 217//----高低指针所指向的元素排序完成后,还得要把中枢元素放到适当的位置 218if(pare(array[pivot],array[low])>0){ 219//如果退出循环时中枢元素大于了低指针或高指针元素时,中枢元素需与low元素交换 220swap(array,low,pivot); 221pivot=low; 222}elseif(pare(array[pivot],array[low])<=0){ 223swap(array,low-1,pivot); 224pivot=low-1; 225} 226 227//返回中枢元素所在位置,以便下次分区 228returnpivot; 229} 230 231/** 232*测试 233*@paramargs 234*/ 235publicstaticvoidmain(String[]args){ 236Integer[]intgArr={3,1,1,1,1,1,1}; 237QuickSort 238QuickSort.testSort(sort,intgArr); 239QuickSort.testSort(sort,null); 240} 241} 归并排序 Java代码 242packagesort; 243 244importjava.lang.reflect.Array; 245importjava.util.Comparator; 246 247/** 248*归并排序算法 249*@authorjzj 250*@date2009-12-11 251* 252*@param 253*/ 254publicclassMergeSort 255 256/** 257*排序算法的实现,对数组中指定的元素进行排序 258*@paramarray待排序的数组 259*@paramfrom从哪里开始排序 260*@paramend排到哪里 261*@paramc比较器 262*/ 263publicvoidsort(E[]arr,intfrom,intend,Comparator 264partition(arr,from,end,c); 265} 266 267/** 268*递归划分数组 269*@paramarr 270*@paramfrom 271*@paramend 272*@paramcvoid 273*/ 274privatevoidpartition(E[]arr,intfrom,intend,Comparator 275//划分到数组只有一个元素时才不进行再划分 276if(from 277//从中间划分成两个数组 278intmid=(from+end)/2; 279partition(arr,from,mid,c); 280partition(arr,mid+1,end,c); 281//合并划分后的两个数组 282merge(arr,from,end,mid,c); 283} 284} 285 286/** 287*数组合并,合并过程中对两部分数组进行排序 288*前后两部分数组里是有序的 289*@paramarr 290*@paramfrom 291*@paramend 292*@parammid 293*@paramcvoid 294*/ 295privatevoidmerge(E[]arr,intfrom,intend,intmid,Comparator 296E[]tmpArr=(E[])Array.newInstance(arr[0].getClass(),end-from+1); 297inttmpArrIndex=0;//指向临时数组 298intpart1ArrIndex=from;//指向第一部分数组 299intpart2ArrIndex=mid+1;//指向第二部分数组 300 301//由于两部分数组里是有序的,所以每部分可以从第一个元素依次取到最后一个元素,再对两部分 302//取出的元素进行比较。 只要某部分数组元素取完后,退出循环 303while((part1ArrIndex<=mid)&&(part2ArrIndex<=end)){ 304//从两部分数组里各取一个进行比较,取最小一个并放入临时数组中 305if(pare(arr[part1ArrIndex],arr[part2ArrIndex])<0){ 306//如果第一部分数组元素小,则将第一部分数组元素放入临时数组中,并且临时数组指针 307//tmpArrIndex下移一个以做好下次存储位置准备,前部分数组指针part1ArrIndex 308//也要下移一个以便下次取出下一个元素与后部分数组元素比较 309tmpArr[tmpArrIndex++]=arr[part1ArrIndex++]; 310}else{ 311//如果第二部分数组元素小,则将第二部分数组元素放入临时数组中 312tmpArr[tmpArrIndex++]=arr[part2ArrIndex++]; 313} 314} 315//由于退出循环后,两部
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 排序 算法 比较