///归并排序///
//归并方法:把两个有序子序列合并成一个有序序列
public void merge(int[]a, int[]b,int left, int mid, int right){
//该方法的具体功能:把左子序列a[left:mid] 和 右子序列a[mid+1:right] 归并到 b[left:right]
int p=left;//遍历左子序列的游标--a[left:mid]
int r=mid+1;//遍历右子序列的游标--a[mid+1:right]
int k=left; //归并结果序列的游标---当前归并元素在结果集中的位置--b[left:right]
while(p<=mid && r<=right){//归并两个子序列,直到其中一个子序列中所有元素都被归并完
if(a[p]<a[r]){
b[k++]=a[p++];
}else{
b[k++]=a[r++];
}
}
//经过上面的循环,一定有一个子序列已经归并完成。此时,只要把没归并完的那个子序列剩下的元素直接照搬到结果集b[]中
if(p>mid){//左子序列排完,,照搬右子序列
for(int i=r; i<=right;i++){
b[k++]=a[i];
}
}else{//右子序列排完,,照搬左子序列
for(int i=p;i<=mid;i++){
b[k++]=a[i];
}
}
}
@Test//测试归并方法merge()
public void mergeTest(){
int a[] = {60,40, 1,3,5,10,12,35, -1,0,2,3,4,8,20,24,36};
int b[] = new int[a.length];
merge(a,b,2,7,a.length-3);
print(b);
}
//调用merge()实现排普通序列---其实用快排做这功能更好,这里只是学习
//把数组a[left:right]范围内的元素进行排序--采用归并
public void mergeSort(int a[], int left, int right){
if(left<right){//至少要有2个元素,才进行
//先分解
int mid=(left+right)/2; //取中间点二分成两个子区间
mergeSort(a,left,mid);
mergeSort(a,mid+1,right);
//再归并
int b[]=new int[a.length];
merge(a,b,left,mid,right);
copyArray(a,b,left,right);//自定义方法,实现:把辅助序列b中的数据拷回到a中
}
}
//自定义方法,实现:把辅助序列b中的数据拷回到a中
private void copyArray(int[] a, int[] b, int left, int right) {
for(int i=left;i<=right;i++){
a[i]=b[i];
}
}
@Test
public void mergeSortTest(){
int a[] = {60,40, 1,3,5,10,12,35, -1,0,2,3,4,8,20,24,36};
mergeSort(a, 0, a.length-1);
print(a);
}
}
归并排序(把两个有序子序列合并成一个有序序列)
最新推荐文章于 2022-12-05 10:05:56 发布