Java中用于填充空间希尔伯特曲线的递归算法

4

我正在学习Java编程,已经到达了Java编程中的递归部分。我理解递归方法的基本知识,并尝试编写填充空间希尔伯特曲线(和列维C曲线),到目前为止一切都很顺利,直到实际递归部分。我在编写递归方法时遇到了困难,希望有人能帮助我。此外,我知道需要在DrawHilbert方法中实现。

public class HilbertCurve extends JPanel {
int N;

/**
 * Constructor for Hilbert Curve
 */
public HilbertCurve () 
{
    Scanner myKeyboard = new Scanner(System.in);
    System.out.println("Enter an integer number to indicate the level of recursive depth: ");
    N = myKeyboard.nextInt();
    // Create a JFrame - a window that will appear on your screen
    JFrame f = new JFrame();

    // Tells the program to quit if you close the window
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // Puts your drawing into the window (the JFrame)
    f.add(new JScrollPane(this));
    // Changes the size of the window on the screen
    f.setSize(600, 600);
    // Changes where the window will appear on your screen
    f.setLocation(200, 200);
    // Makes the window appear
    f.setVisible(true);
}
public void setupHilbert (Turtle turtle) 
{
    turtle.penup();
    turtle.setXY(0,0);

    // draw a simple rectangle that is 100x50 pixels
    turtle.pendown();

    drawHilbert(turtle, N); 
}

public void drawHilbert(Turtle turtle, int n) {

    if (n == 0) return;
    turtle.changeColor(Color.GREEN);
    turtle.changeWidth(2);
    turtle.left(-90);
    turtle.forward(100);
    turtle.left(90);
    turtle.forward(100);
    turtle.left(90);
    turtle.forward(100);
    turtle.left(-90);
    turtle.penup();
}

protected void paintComponent(Graphics g)
{
    Turtle turtle = new Turtle((Graphics2D) g, getBounds());

    turtle.setHeadingMode(Turtle.DEGREE);
    setupHilbert(turtle);

}


// plot a Hilbert curve of order N
public static void main(String[] args) 
{
    Scanner myKeyboard = new Scanner(System.in);
    HilbertCurve test = new HilbertCurve();
}

}


有趣的是,绘制希尔伯特曲线的迭代算法也不比递归方法更难:https://marcin-chwedczuk.github.io/iterative-algorithm-for-drawing-hilbert-curve - csharpfolk
1个回答

1
递归的显著特征是函数调用自身。我期望在某个地方看到对drawHilbert()的调用,但我没有看到。
请仔细注意您的停止条件,否则您的递归调用将无限添加到堆栈中,导致OutOfMemoryError。
我不熟悉您的问题,但这是否是您缺少的内容?
public void drawHilbert(Turtle turtle, int n) {

    if (n == 0) return;
    turtle.changeColor(Color.GREEN);
    turtle.changeWidth(2);
    turtle.left(-90);
    turtle.forward(100);
    turtle.left(90);
    turtle.forward(100);
    turtle.left(90);
    turtle.forward(100);
    turtle.left(-90);
    turtle.penup();
    drawHilbert(turtle, --n);  // is this where your recursion should go?
}

更新:这个网站看起来很相关。

http://people.cs.aau.dk/~normark/prog3-03/html/notes/fu-intr-2_themes-hilbert-sec.html


好的,没错。调用本身是递归函数的三个组成部分之一。所以我添加了这个:如果(n == 0)返回;turtle.changeColor(Color.BLUE);turtle.changeWidth(2);turtle.left(-90);drawHilbert(turtle, N-1);turtle.forward(100); turtle.left(90); drawHilbert(turtle, N-1); turtle.forward(100); turtle.left(90); drawHilbert(turtle, N-1); turtle.forward(100); turtle.left(-90); turtle.penup();但似乎不起作用。我离成功更近了吗? - Christopher
我不知道 - 我需要更好地了解你的问题。N-1 对我来说看起来不对,因为你必须从你传递的参数 n 中减去。Java是大小写敏感的,所以 "n" 和 "N" 是不同的变量名。 - duffymo
不要道歉,你在学习并且付出了很好的努力。看看我发布的链接,我认为它会解释递归在哪里发挥作用。 - duffymo
你是对的。我很抱歉。正如你所看到的,我刚开始接触这个。所以我将n改为N。那是表示我想要程序显示的递归级别(或递归深度)的实例变量。因此,N = 1将是基本情况,然后2、3、4等将更具填充性。当我将n改为N时,程序可以运行,但仅将基本情况的位置顺时针旋转90度,而未添加递归深度。 - Christopher
这里更深入地理解问题会非常有用。请记住,每个递归调用都可以表示为一个迭代调用,反之亦然。先使用循环实现来使您的代码正常工作,然后再考虑递归。 - duffymo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接