go语言归并 go归并排序( 二 )


使用递归的代码如下 。优点是描述算法过程思路清晰,缺点是使用递归,mergeSort()函数频繁地自我调用 。长度为n的数组最终会调用mergeSort()函数 2n-1次,这意味着一个长度超过1500的数组会在Firefox上发生栈溢出错误 。可以考虑使用迭代来实现同样的功能 。function merge(left, right){var result=[];while(left.length0right.length0){if(left[0]right[0]){/*shift()方法用于把数组的第一个元素从其中删除,并返回第一个元素的值 。*/result.push(left.shift());}else{result.push(right.shift());}}return result.concat(left).concat(right);}function mergeSort(items){if(items.length == 1){return items;}var middle = Math.floor(items.length/2),left = items.slice(0, middle),right = items.slice(middle);return merge(mergeSort(left), mergeSort(right));}非递归算法(C++)#includeiostream#includectime#includecstring#includecstdlibusing namespace std;/**将a开头的长为length的数组和b开头长为right的数组合并n为数组长度,用于最后一组*/void Merge(int* data,int a,int b,int length,int n){ int right; if(b+length-1 = n-1) right = n-b; else right = length; int* temp = new int[length+right]; int i=0, j=0; while(i=length-1j=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)); }else if(i == length){memcpy(temp + i + j, data + b + j, (right - j)*sizeof(int));} memcpy(data+a, temp, (right + length) * sizeof(int)); delete [] temp;}void MergeSort(int* data, int n){ int step = 1; while(stepn){for(int i=0; i=n-step-1; i+=2*step)Merge(data, i, i+step, step, n);//将i和i+step这两个有序序列进行合并//序列长度为step//当i以后的长度小于或者等于step时,退出step*=2;//在按某一步长归并序列之后,步长加倍 }}int main(){ int n; cinn; int* data = https://www.04ip.com/post/new int[n]; if(!data) exit(1); int k = n; while(k--){cindata[n-k-1]; } clock_t s = clock(); MergeSort(data, n); clock_t e = clock(); k=n; while(k--){coutdata[n-k-1]' '; } coutendl; coutthe algorithm usede-smiliseconds.endl; delete data; return 0;}二路归并
ConstFI='in.txt';FO='out.txt';MaxN=10000;TypeTIndex=Longint;TDat=Array[0..MaxN]OfTIndex;VarN:TIndex;Dat:TDat;Tmp:TDat;ProcedureMerge(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;ProcedureSort(L,R:TIndex);VarMid:TIndex=0;BeginMid:=(L+R)Shr1;If(LMid)ThenSort(L,Mid);If(Mid+1R)ThenSort(Mid+1,R);Merge(L,Mid,R);ForMid:=LToRDoDat[Mid]:=Tmp[Mid];End;ProcedureInit;VarI:TIndex;BeginFillChar(Dat,SizeOf(Dat),0);Readln(N);ForI:=1ToNDoRead(Dat[I]);End;ProcedureMain;BeginSort(1,N);End;ProcedureFinal;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归并排序完整源代码例子://合并子函数procedureTForm1.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是数组右下标 。procedureTForm1.MergeSort(vardatas:arrayofInteger;left,right:Integer);varmid:Integer;i:Integer;beginmid:=0;if(leftright)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;//调用方法:procedureTForm1.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;

推荐阅读