归并排序 递归 java_JAVA学习之递归与归并排序

从前有座山,山里有座庙,庙里有个老和尚,老和尚正在给小和尚讲故事,

说”从前有座山,山里有座庙,庙里有个老和尚,老和尚正在给小和尚讲故事,

说‘从前有座山,山里有座庙,庙里有个老和尚,老和尚正在给小和尚讲故事,

说”从前有座山,山里有座庙,庙里有个老和尚,老和尚正在给小和尚讲故事,说‘……’“’“

以上就是递归的一个故事

递归就是在过程或函数里调用自身

在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。

递归的典型代码就是求n的阶乘和斐波纳契数列

//斐波那契数列,在方法中调用自身

public static int f(intn)

{if (n < 3)

{return 1;

}else{return f(n - 1) + f(n - 2);

}

}//求n的阶乘在,方法中调用自身

public static int ff(intn)

{if (n < 2)

{return 1;

}else{return n * ff(n - 1);

}

}

归并排序

所谓归并,就是把两个或者两个以上的有序表合并成一个新的有序表的过程。

归并操作的过程如下:

1.申请空间,使其大小为两个已经排序串行之和,该空间用来存放合并后的串行

2.设定两个指针,最初位置分别为两个已经排序串行的起始位置

3.比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置

4.重复步骤3直到某一指针到达串行尾

5.将另一串行剩下的所有元素直接复制到合并串行尾

public static void merge(int[] nums, int low, int mid, inthigh)

{//申请空间

int[] temp = new int[high - low + 1];//设定指针

int i =low;int j = mid + 1;int k = 0;//把较小的数先移到新数组中

while (i <= mid && j <=high)

{if (nums[i]

{

temp[k++] = nums[i++];

}else{

temp[k++] = nums[j++];

}

}//把左边剩余的数移入数组

while (i <=mid)

{

temp[k++] = nums[i++];

}//把右边边剩余的数移入数组

while (j <=high)

{

temp[k++] = nums[j++];

}//把新数组中的数覆盖nums数组

for (int k2 = 0; k2 < temp.length; k2++)

{

nums[k2+ low] =temp[k2];

}

}

归并排序的原理是,先把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列,

归并的前提是先把要排序的序列分为若干个字序列,然后才归并。在拆分数列的时候,就要用到拆分,直到不能再拆为止。

如一个数列{9,8,7,6,5,4,3,2,1}

先分成{9,8,7,6,5}和{4,3,2,1}

然后再分成{9,8,7}和{6,5}和{4,3}和{2,1}

然后再分{9,8}、{6}、{5}、{4}、{3}、{2}、{1}

然后再合并起来,小在的前面,大的在后面,没有比较的在后面填充数列。

以下是归并排序的完整代码,其中在排序的时候用到了递归拆分数列,就是在方法sort()里面

public classMyClass

{public static voidmain(String[] args)

{int[] arr = new int[] { 9, 8, 7, 6, 5, 4, 3, 2, 1};

arr= sort(arr, 0, arr.length - 1);for (int i = 0; i < arr.length; i++)

{

System.out.print(arr[i] + "");

}

}//斐波那契数列

public static int f(intn)

{if (n < 3)

{return 1;

}else{return f(n - 1) + f(n - 2);

}

}//求n的阶乘

public static int ff(intn)

{if (n < 2)

{return 1;

}else{return n * ff(n - 1);

}

}//排序

public static int[] sort(int[] nums, int low, inthigh)

{//把一个序列从中间的位置分开

int mid = (low + high) / 2;if (low

{//左边的序列递归

sort(nums, low, mid);//右边的序列递归

sort(nums, mid + 1, high);//左右归并

merge(nums, low, mid, high);

}returnnums;

}public static void merge(int[] nums, int low, int mid, inthigh)

{//申请空间

int[] temp = new int[high - low + 1];//设定指针

int i =low;int j = mid + 1;int k = 0;//把较小的数先移到新数组中

while (i <= mid && j <=high)

{if (nums[i]

{

temp[k++] = nums[i++];

}else{

temp[k++] = nums[j++];

}

}//把左边剩余的数移入数组

while (i <=mid)

{

temp[k++] = nums[i++];

}//把右边边剩余的数移入数组

while (j <=high)

{

temp[k++] = nums[j++];

}//把新数组中的数覆盖nums数组

for (int k2 = 0; k2 < temp.length; k2++)

{

nums[k2+ low] =temp[k2];

}

}

}

其实整个归并排序,难的不是排序,也不是归并,而是使用递归拆分,而且还是要左右拆分。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值