典型的汉诺塔圆盘移动方法:
/**
* 每次只能移动一个圆盘,将原本放在初始位置的圆盘借助中间位置按原来的顺序移动到目标位置
*
* @param topN 开始时在初始位置共有多少圆盘
* @param from 初始位置
* @param inter 中间位置
* @param to 目标位置
*/
public static void doTowers(int topN, char from, char inter, char to)
{
if(topN == 1)//将最后一个圆盘放到最终位置
System.out.println(" DISK 1 FROM " + from + " TO " + to);
else
{
doTowers(topN - 1, from, to, inter);//借助于目标位置先将除最后一个圆盘的所有圆盘放在中间位置
System.out.println(" DISK " + topN + " FROM " + from + " TO " + to);
doTowers(topN - 1, inter, from, to);//借助于初始位置将已经处于中间位置的除最后一个圆盘的所有圆盘放在目标位置
}
}
归并排序类:
/**
* @param args 归并排序,递归方法
* @author xujp1
*/
class Darray
{
private final long[] theArray;
private int eItem;
public Darray(int max)
{
theArray = new long[max];
eItem = 0;
}
public void insert(long value)
{
theArray[eItem++] = value;
}
public void display()
{
for(int i = 0; i < eItem; i++)
System.out.print(theArray[i] + " ");
System.out.println();
}
public void mergeSort()
{
long[] workspace = new long[eItem];
recMergeSort(workspace, 0, eItem - 1);
}
public void recMergeSort(long[] workspace, int lowerBound, int upperBound)
{
if(lowerBound == upperBound)
return;
else
{
int mid = (lowerBound + upperBound) / 2;
recMergeSort(workspace, lowerBound, mid); // 归并前半部分
recMergeSort(workspace, mid + 1, upperBound); // 归并后半部分
merge(workspace, lowerBound, mid + 1, upperBound);
}
}
/**
* 类似于两个数组从小到大合并到第三个数组
*
* @param workspace 中间变量(类似于第三个数组,即合并的结果)
* @param lowerPtr 数组下标最左边(类似于第一个数组的index1)
* @param highPtr 数组下标中间位置(类似于第二个数组的index1)
* @param upperBound 数组下标最右边,比较结束后可用此参数。
*/
public void merge(long[] workspace, int lowerPtr, int highPtr, int upperBound)
{
int j = 0;
int lowerBound = lowerPtr; // lowerBound后续用到
int mid = highPtr - 1; // 作为跟lowerPtr比较的参数
int n = upperBound - lowerPtr + 1; // 本次归并后的数组大小
/**
* 最左边的值和中间的值进行比较,哪个数比较小则赋值给workspace,同时下标加1。
*/
while (lowerPtr <= mid && highPtr <= upperBound)
if(theArray[lowerPtr] > theArray[highPtr])
workspace[j++] = theArray[highPtr++];
else
workspace[j++] = theArray[lowerPtr++];
while (lowerPtr <= mid)
workspace[j++] = theArray[lowerPtr++];
while (highPtr <= upperBound)
workspace[j++] = theArray[highPtr++];
for(int i = 0; i < n; i++)
theArray[lowerBound + i] = workspace[i];
}
}
注:以上代码均出自JAVA数据结构和算法第二版
分享到:
相关推荐
9. 递归的归并排序:归并排序通常使用递归实现,通过递归调用自身对数组的前半部分和后半部分进行排序,然后用归并操作合并结果。这种递归方式使算法具有清晰的逻辑结构。 10. 基数排序:基数排序是一种非比较型...
在C++中实现非递归归并排序,主要涉及以下几个步骤: 1. **分割数组**:首先,我们需要将原始数组分割成两个部分。这通常通过一个中间索引完成,将数组分为两半。例如,如果我们有一个大小为n的数组,我们可以选择...
这里有三个主要的排序算法:归并排序、消除递归的归并排序和快速排序,它们都是在Java编程语言中实现的。让我们深入探讨这些算法及其Java实现。 1. **归并排序(Merge Sort)** 归并排序是一种基于分治思想的排序...
c++实现的合并排序算法 用递归和非递归两种方式实现的
合并排序,使用非递归的方式,使输入的数组按升序排列
三、实现非递归归并排序的步骤 1. 将需要排序的数组分成小数组,并对每个小数组进行排序。 2. 使用迭代的方式将已排序的小数组合并成一个大的已排序数组。 3. 使用临时数组来存储中间结果,以避免对原始数组的修改...
非递归归并排序.cpp
标题与描述均提到了“8645 归并排序(非递归算法)...非递归归并排序作为归并排序的一个变种,尤其适合于那些受限于内存或性能需求的场合,通过避免递归带来的额外开销,可以在一定程度上提升算法的运行效率和稳定性。
9. **递归的归并排序**:归并排序的实现方式之一,直接使用递归调用自身来完成数组的划分和合并过程,其基本思想与归并排序一致。 10. **基数排序**(Radix Sort):一种非比较型整数排序算法,其原理是将整数按...
递归调用归并排序.cpp
### 递归归并排序算法 #### 一、概述 归并排序是一种高效的排序算法,其核心思想是分而治之。它通过递归地将数组分成两半,然后对每一半进行排序,并最终合并两个有序数组来实现整体排序。由于归并排序采用的是...
非递归版本的合并排序,也称为迭代版本,通过使用栈或者循环来模拟递归的过程。基本步骤与递归类似,首先将数组分为两半,但不会立即进行递归调用。而是将这些子任务存储在一个数据结构(如栈)中,每次从栈中取出...
非递归归并排序详细分析,Java实现. 非常详细,基本上可以看明白
归并排序的非递归排序的代码解析
自然合并排序是对合并排序的非递归形式的一种改进,很好很有用
递归实现的二路归并排序算法,其中对结构体按其内部一个关键字(本例是对一个任务结构体,按其收益排序)进行排序
归并排序同样采用分治策略,将数组分为两半,分别排序后合并。它的特点是稳定性好,但需要额外的空间来存储临时数组。 总的来说,递归函数在C语言中的应用丰富多样,递归排序法是其中的经典示例。掌握递归的思想和...
3. **合并操作**:在归并排序中,合并是将两个已经排序的子数组合并成一个有序数组的过程。这个过程中需要用到额外的存储空间,通常是一个与原数组同样大小的临时数组。比较两个子数组的元素,依次将较小的元素放入...
6. **二路归并排序**:将数组分成两半,分别对左右两部分进行排序,然后合并两个已排序的部分。C#实现中,通常需要额外的空间来存储中间结果,所以是稳定的排序算法。二路归并排序的时间复杂度在所有情况下都保持在O...
一个Java小程序,利用递归思想实现的归并排序算法。其中有两个类,排序数据是写死在main方法中的。