A. java怎么实现排序
Java实现几种常见排序方法
日常操作中常见的排序方法有:冒泡排序、快速排序、选择排序、插入排序、希尔排序,甚至还有基数排序、鸡尾酒排序、桶排序、鸽巢排序、归并排序等。
以下常见算法的定义
1. 插入排序:插入排序基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。插入排序的基本思想是:每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
2. 选择排序:选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法。
3. 冒泡排序:冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。
4. 快速排序:快速排序(Quicksort)是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
5. 归并排序:归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
6. 希尔排序:希尔排序(Shell Sort)是插入排序的一种。也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。
https://www.cnblogs.com/wangmingshun/p/5635292.html
B. JAVA中有哪几种常用的排序方法每个排序方法的实现思路是如何的每个方法的思想是什么
一、冒泡排序
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较 a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对 a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。
优点:稳定;
缺点:慢,每次只能移动相邻两个数据。
二、选择排序
冒泡排序的改进版。
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法。
n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果:
①初始状态:无序区为R[1..n],有序区为空。
②第1趟排序
在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
……
③第i趟排序
第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R(1≤i≤n- 1)。该趟排序从当前无序区中选出关键字最小的记录 R[k],将它与无序区的第1个记录R交换,使R[1..i]和R分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。
这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。
优点:移动数据的次数已知(n-1次);
缺点:比较次数多。
三、插入排序
已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、 b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来 a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a)
优点:稳定,快;
缺点:比较次数不一定,比较次数越少,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。
三、缩小增量排序
由希尔在1959年提出,又称希尔排序(shell排序)。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、 a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。
优点:快,数据移动少;
缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。
四、快速排序
快速排序是目前已知的最快的排序方法。
已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先任取数据 a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n] 两组数据进行快速排序。
优点:极快,数据移动少;
缺点:不稳定。
五、箱排序
已知一组无序正整数数据a[1]、a[2]、……a[n],需将其按升序排列。首先定义一个数组x[m],且m>=a[1]、a[2]、……a[n],接着循环n次,每次x[a]++.
优点:快,效率达到O(1)
缺点:数据范围必须为正整数并且比较小
六、归并排序
归并排序是多次将两个或两个以上的有序表合并成一个新的有序表。最简单的归并是直接将两个有序的子表合并成一个有序的表。
归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要.这也是它比快速排序优势的地方.
C. 归并排序的示例代码
归并排序原理
归并排序具体工作原理如下(假设序列共有n个元素):
将序列每相邻两个数字进行归并操作(merge),形成floor(n/2)个序列,排序后每个序列包含两个元素
将上述序列再次归并,形成floor(n/4)个序列,每个序列包含四个元素
重复步骤2,直到所有元素排序完毕
示例代码
Go语言 funcmergeSort(r[]int)[]int{length:=len(r)iflength<=1{returnr}num:=length/2left:=mergeSort(r[:num])right:=mergeSort(r[num:])returnmerge(left,right)}funcmerge(left,right[]int)(result[]int){l,r:=0,0forl<len(left)&&r<len(right){ifleft[l]<right[r]{result=append(result,left[l])l++}else{result=append(result,right[r])r++}}result=append(result,left[l:]...)result=append(result,right[r:]...)return}Java语言 packagealgorithm;publicclassMergeSort{//privatestaticlongsum=0;/***<pre>*二路归并*原理:将两个有序表合并和一个有序表*</pre>**@parama*@params*第一个有序表的起始下标*@paramm*第二个有序表的起始下标*@paramt*第二个有序表的结束小标**/privatestaticvoidmerge(int[]a,ints,intm,intt){int[]tmp=newint[t-s+1];inti=s,j=m,k=0;while(i<m&&j<=t){if(a[i]<=a[j]){tmp[k]=a[i];k++;i++;}else{tmp[k]=a[j];j++;k++;}}while(i<m){tmp[k]=a[i];i++;k++;}while(j<=t){tmp[k]=a[j];j++;k++;}System.array(tmp,0,a,s,tmp.length);}/****@parama*@params*@paramlen*每次归并的有序集合的长度*/publicstaticvoidmergeSort(int[]a,ints,intlen){intsize=a.length;intmid=size/(len<<1);intc=size&((len<<1)-1);//-------归并到只剩一个有序集合的时候结束算法-------//if(mid==0)return;//------进行一趟归并排序-------//for(inti=0;i<mid;++i){s=i*2*len;merge(a,s,s+len,(len<<1)+s-1);}//-------将剩下的数和倒数一个有序集合归并-------//if(c!=0)merge(a,size-c-2*len,size-c,size-1);//-------递归执行下一趟归并排序------//mergeSort(a,0,2*len);}publicstaticvoidmain(String[]args){int[]a=newint[]{4,3,6,1,2,5};mergeSort(a,0,1);for(inti=0;i<a.length;++i){System.out.print(a[i]+);}}}Python语言 defMergeSort(lists):iflen(lists)<=1:returnlistsnum=int(len(lists)/2)left=MergeSort(lists[:num])right=MergeSort(lists[num:])returnMerge(left,right)defMerge(left,right):r,l=0,0result=[]whilel<len(left)andr<len(right):ifleft[l]<right[r]:result.append(left[l])l+=1else:result.append(right[r])r+=1result+=right[r:]result+=left[l:]returnresultprintMergeSort([1,2,3,4,5,6,7,90,21,23,45])C语言 #include<stdlib.h>#include<stdio.h>voidMerge(intsourceArr[],inttempArr[],intstartIndex,intmidIndex,intendIndex){inti=startIndex,j=midIndex+1,k=startIndex;while(i!=midIndex+1&&j!=endIndex+1){if(sourceArr[i]>=sourceArr[j])tempArr[k++]=sourceArr[j++];elsetempArr[k++]=sourceArr[i++];}while(i!=midIndex+1)tempArr[k++]=sourceArr[i++];while(j!=endIndex+1)tempArr[k++]=sourceArr[j++];for(i=startIndex;i<=endIndex;i++)sourceArr[i]=tempArr[i];}//内部使用递归voidMergeSort(intsourceArr[],inttempArr[],intstartIndex,intendIndex){intmidIndex;if(startIndex<endIndex){midIndex=(startIndex+endIndex)/2;MergeSort(sourceArr,tempArr,startIndex,midIndex);MergeSort(sourceArr,tempArr,midIndex+1,endIndex);Merge(sourceArr,tempArr,startIndex,midIndex,endIndex);}}intmain(intargc,char*argv[]){inta[8]={50,10,20,30,70,40,80,60};inti,b[8];MergeSort(a,b,0,7);for(i=0;i<8;i++)printf(%d,a[i]);printf(
);return0;}PHP语言 //merge函数将指定的两个有序数组(arr1arr2,)合并并且排序//我们可以找到第三个数组,然后依次从两个数组的开始取数据哪个数据小就先取哪个的,然后删除掉刚刚取过///的数据functional_merge($arrA,$arrB){$arrC=array();while(count($arrA)&&count($arrB)){//这里不断的判断哪个值小,就将小的值给到arrC,但是到最后肯定要剩下几个值,//不是剩下arrA里面的就是剩下arrB里面的而且这几个有序的值,肯定比arrC里面所有的值都大所以使用$arrC[]=$arrA['0']<$arrB['0']?array_shift($arrA):array_shift($arrB);}returnarray_merge($arrC,$arrA,$arrB);}//归并排序主程序functional_merge_sort($arr){$len=count($arr);if($len<=1)return$arr;//递归结束条件,到达这步的时候,数组就只剩下一个元素了,也就是分离了数组$mid=intval($len/2);//取数组中间$left_arr=array_slice($arr,0,$mid);//拆分数组0-mid这部分给左边left_arr$right_arr=array_slice($arr,$mid);//拆分数组mid-末尾这部分给右边right_arr$left_arr=al_merge_sort($left_arr);//左边拆分完后开始递归合并往上走$right_arr=al_merge_sort($right_arr);//右边拆分完毕开始递归往上走$arr=al_merge($left_arr,$right_arr);//合并两个数组,继续递归return$arr;}$arr=array(12,5,4,7,8,3,4,2,6,4,9);print_r(al_merge_sort($arr));Pascal语言 programmergesort_1;constmaxn=7;typearr=array[1..maxn]ofinteger;vara,b,c:arr;i:integer;proceremerge(r:arr;l,m,n:integer;varr2:arr);vari,j,k,p:integer;begini:=l;j:=m+1;k:=l-1;while(i<=m)and(j<=n)dobegink:=k+1;ifr[i]<=r[j]thenbeginr2[k]:=r[i];i:=i+1endelsebeginr2[k]:=r[j];j:=j+1;endend;ifi<=mthenforp:=itomdobegink:=k+1;r2[k]:=r[p];end;ifj<=nthenforp:=jtondobegink:=k+1;r2[k]:=r[p];end;end;proceremergesort(varr,r1:arr;s,t:integer);vark:integer;c:arr;beginifs=tthenr1[s]:=r[s]elsebegink:=(s+t)div2;mergesort(r,c,s,k);mergesort(r,c,k+1,t);merge(c,s,k,t,r1)end;end;beginwrite('Enterdata:');fori:=1tomaxndoread(a[i]);mergesort(a,b,1,maxn);fori:=1tomaxndowrite(b[i]:9);writeln;end.//============================================programmergesort_2;constmax=100000;vara,r:array[1..max]oflongint;n,i:longint;proceremsort(s,t:longint);varm,i,j,k:longint;beginifs=tthenexit;m:=(s+t)div2;msort(s,m);msort(m+1,t);i:=s;j:=m+1;k:=s;while(i<=m)and(j<=t)dobeginifa[i]<a[j]thenbeginr[k]:=a[i];inc(i);inc(k);endelsebeginr[k]:=a[j];inc(j);inc(k);end;end;whilei<=mdobeginr[k]:=a[i];inc(i);inc(k);end;whilej<=tdobeginr[k]:=a[j];inc(j);inc(k);end;fori:=stotdoa[i]:=r[i];end;beginreadln(n);fori:=1tondoread(a[i]);msort(1,n);fori:=1tondowriteln(a[i]);end.Basic语言 SubMergeSort(Array()AsInteger,FirstAsInteger,LastAsInteger)DimmidAsInteger=0Iffirst<lastThenmid=(first+last)2MergeSort(Array,first,mid);MergeSort(Array,mid+1,last);Merge(Array,first,mid,last);EndIfEndSub/*以下示例代码实现了归并操作。array[]是元素序列,其中从索引p开始到q位置,按照升序排列,同时,从(q+1)到r也已经按照升序排列,merge()函数将把这两个已经排序好的子序列合并成一个排序序列。结果放到array中。*//***0<=p<=q<r,subarrayarray[p..q]andarray[q+1..r]arealreadysorted.*themerge()functionmergesthetwosub-arraysintoonesortedarray.*/voidMerge(intarray[],intp,intq,intr){inti,k;intbegin1,end1,begin2,end2;int*temp=(int*)malloc((r-p+1)*sizeof(int));begin1=p;end1=q;begin2=q+1;end2=r;k=0;while((begin1<=end1)&&(begin2<=end2)){if(array[begin1]<=array[begin2]){temp[k]=array[begin1];begin1++;}else{temp[k]=array[begin2];begin2++;}k++;}while(begin1<=end1||begin2<=end2){if(begin1<=end1){temp[k++]=array[begin1++];}if(begin2<=end2){temp[k++]=array[begin2++];}}for(i=0;i<=(r-p);i++)array[p+i]=temp[i];free(temp);}JavaScript语言
使用递归的代码如下。优点是描述算法过程思路清晰,缺点是使用递归,mergeSort()函数频繁地自我调用。长度为n的数组最终会调用mergeSort()函数 2n-1次,这意味着一个长度超过1500的数组会在Firefox上发生栈溢出错误。可以考虑使用迭代来实现同样的功能。 functionmerge(left,right){varresult=[];while(left.length>0&&right.length>0){if(left[0]<right[0]){/*shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。*/result.push(left.shift());}else{result.push(right.shift());}}returnresult.concat(left).concat(right);}functionmergeSort(items){if(items.length==1){returnitems;}varmiddle=Math.floor(items.length/2),left=items.slice(0,middle),right=items.slice(middle);returnmerge(mergeSort(left),mergeSort(right));}非递归算法(C++) #include<iostream>#include<ctime>#include<cstring>#include<cstdlib>usingnamespacestd;/**将a开头的长为length的数组和b开头长为right的数组合并n为数组长度,用于最后一组*/voidMerge(int*data,inta,intb,intlength,intn){intright;if(b+length-1>=n-1)right=n-b;elseright=length;int*temp=newint[length+right];inti=0,j=0;while(i<=length-1&&j<=right-1){if(data[a+i]<=data[b+j]){temp[i+j]=data[a+i];i++;}else{temp[i+j]=data[b+j];j++;}}if(j==right){//a中还有元素,且全都比b中的大,a[i]还未使用memcpy(temp+i+j,data+a+i,(length-i)*sizeof(int));}elseif(i==length){memcpy(temp+i+j,data+b+j,(right-j)*sizeof(int));}memcpy(data+a,temp,(right+length)*sizeof(int));delete[]temp;}voidMergeSort(int*data,intn){intstep=1;while(step<n){for(inti=0;i<=n-step-1;i+=2*step)Merge(data,i,i+step,step,n);//将i和i+step这两个有序序列进行合并//序列长度为step//当i以后的长度小于或者等于step时,退出step*=2;//在按某一步长归并序列之后,步长加倍}}intmain(){intn;cin>>n;int*data=newint[n];if(!data)exit(1);intk=n;while(k--){cin>>data[n-k-1];}clock_ts=clock();MergeSort(data,n);clock_te=clock();k=n;while(k--){cout<<data[n-k-1]<<'';}cout<<endl;cout<<thealgorithmused<<e-s<<miliseconds.<<endl;deletedata;return0;}二路归并
ConstFI='in.txt';FO='out.txt';MaxN=10000;TypeTIndex=Longint;TDat=Array[0..MaxN]OfTIndex;VarN:TIndex;Dat:TDat;Tmp:TDat;ProcereMerge(L,Mid,R:TIndex);VarP1,P2:TIndex;E1,E2:TIndex;P:TIndex;I:TIndex;BeginP1:=L;P2:=Mid+1;P:=L;RepeatIf(Dat[P1]<=Dat[P2])ThenBeginTmp[P]:=Dat[P1];Inc(P1);Inc(P);EndElseBeginTmp[P]:=Dat[P2];Inc(P2);Inc(P);End;Until(P1=Mid+1)Or(P2=R+1);If(P1=Mid+1)ThenBeginE1:=P2;E2:=R;EndElseBeginE1:=P1;E2:=Mid;End;ForI:=E1ToE2DoBeginTmp[P]:=Dat[I];Inc(P);End;End;ProcereSort(L,R:TIndex);VarMid:TIndex=0;BeginMid:=(L+R)Shr1;If(L<Mid)ThenSort(L,Mid);If(Mid+1<R)ThenSort(Mid+1,R);Merge(L,Mid,R);ForMid:=LToRDoDat[Mid]:=Tmp[Mid];End;ProcereInit;VarI:TIndex;BeginFillChar(Dat,SizeOf(Dat),0);Readln(N);ForI:=1ToNDoRead(Dat[I]);End;ProcereMain;BeginSort(1,N);End;ProcereFinal;VarI:TIndex;BeginForI:=1ToNDoWrite(Dat[I],'');Writeln;End;BeginAssign(Input,FI);Assign(Output,FO);Reset(Input);Rewrite(Output);Init;Main;Final;Close(Input);Close(Output);End.
Delphi归并排序完整源代码例子: //合并子函数procereTForm1.MergePass(vardatas:arrayofInteger;left,mid,right:Integer);vartmpArr:arrayofInteger;arrLen:Integer;i,k:Integer;begin1,begin2,end1,end2:Integer;beginarrLen:=right-left+1;SetLength(tmpArr,arrLen);begin1:=left;end1:=mid;begin2:=mid+1;end2:=right;k:=0;while((begin1<=end1)and(begin2<=end2))dobeginif(datas[begin1]<datas[begin2])thenbegintmpArr[k]:=datas[begin1];Inc(begin1);endelsebegintmpArr[k]:=datas[begin2];Inc(begin2);end;inc(k);end;while(begin1<=end1)dobegintmpArr[k]:=datas[begin1];Inc(begin1);Inc(k);end;while(begin2<=end2)dobegintmpArr[k]:=datas[begin2];Inc(begin2);Inc(k);end;fori:=0to(right-left)dobegindatas[left+i]:=tmpArr[i];end;end;//排序主函数,left是数组左下标,0开始。right是数组右下标。procereTForm1.MergeSort(vardatas:arrayofInteger;left,right:Integer);varmid:Integer;i:Integer;beginmid:=0;if(left<right)thenbeginmid:=(right+left)div2;showLog('中间索引:'+inttostr(mid));MergeSort(datas,left,mid);MergeSort(datas,mid+1,right);MergePass(datas,left,mid,right);showLog('--->'+getArrayString(datas));//显示数组中间状态end;end;//调用方法:procereTForm1.btn1Click(Sender:TObject);varinArr:array[0..9]ofInteger;beginCopyMemory(@inArr[0],@CTabls[0],SizeOf(Integer)*10);showLog('输入数据:'+getArrayString(inArr));MergeSort(inArr,0,High(inArr));showLog('输出数据:'+getArrayString(inArr));end;
D. java实现归并排序问题
public void mySort(int low,int high){
int lo=low;
int hi=high;
if (lo>=hi) {
return;
}else{
boolean flag=false;
while (lo<hi) {
if (arrs[lo]>arrs[hi]) {
int temp=arrs[lo];
arrs[lo]=arrs[hi];
arrs[hi]=temp;
flag=!flag;
}else{
if (flag) {
lo++;
}else{
hi--;
}
}
}
lo--;
hi++;
mySort(low,lo);
mySort(hi,high);
}
}
这里是复递归加二分法制(排序的方法) 希望能帮到你!!望~~点赞
E. Java 合并排序 求程序
网络文库找了一个http://wenku..com/view/332fd62d453610661ed9f414.html
四、合并排序 1、基本思想
合并排序的基本操作是:首先将待排序序列划分为两个长度相等的子序列;然后分别对两个子序列进行归并排序,得到两个有序的子序列;最后将两个有序的子序列合并成一个有序数列。
MergeSort(A[2*n]) {
divide A[2*n] into A[1,……,n],A[n-1,……,2*n];//划分 MergeSort(A[1,……,n]);//归并排序前半个子序列
MergeSort(A[[n-1,……,2*n]);//归并排序后半个子序列 Merge;//合并 }
2、算法复杂度分析
合并步的时间复杂度为O(n)。合并排序算法的时间复杂度为O(nlog2n)。
3、编程实现
public int[] MergeSort(int[] A, int[] tempA, int s, int t){
//如果序列中有一个以上的元素,即s<t则进行排序
if(s < t){
int center = (s + t) / 2;
MergeSort(A, tempA, s, center)
;//归并排序前半个子序列
MergeSort(A, tempA, center + 1, t);
//归并排序后半个子序列
Merge(A,tempA, s, center, t);
//合并
}
return tempA;
}
public int[] Merge(int[] A, int[] tempA, int s, int m, int t){ int n = t- s + 1;
//n为数据总个数
int i=s;j=m+1;k=s
while(i <= m&& j <= t){
//取A[i]和A[j]中较小者放入tempA[k]
if(A[i]<=A[j]){
tempA[k++] = A[i++]; }
else{
tempA[k++] = A[j++]; } }
if(i<=m) while(i<=m)
tempA[k++]=A[i++];//处理前一个子序列
else while(j<=t)
tempA[k++]=A[j++];//处理后一个子序列
return tempA;
}