Java Sierpinski地毯使用堆栈而不是递归

Java Sierpinski地毯使用堆栈而不是递归,java,recursion,stack,Java,Recursion,Stack,我已经实现了一个使用递归解决问题的解决方案。现在我想使用堆栈而不是递归方法来解决Sierpinski地毯。我试图将递归方法转换到堆栈中,但是当我从递归方法中推送变量时遇到了问题。这是我必须推送和弹出的一段代码 拉丝垫片(x+i*sub,y+j*sub,sub) 调用DrawShield(0、0、729)时,您应该在屏幕上看到以下内容: 递归方法: public void drawGasket(int x, int y, int side) { int sub = side /

我已经实现了一个使用递归解决问题的解决方案。现在我想使用堆栈而不是递归方法来解决Sierpinski地毯。我试图将递归方法转换到堆栈中,但是当我从递归方法中推送变量时遇到了问题。这是我必须推送和弹出的一段代码

拉丝垫片(x+i*sub,y+j*sub,sub)

调用DrawShield(0、0、729)时,您应该在屏幕上看到以下内容:

递归方法:

   public void drawGasket(int x, int y, int side) {
    int sub = side / 3; 

    //Draw center square
    g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));

    if(sub >= 3) {
        //Draw 8 surrounding squares
        for (int i = 0; i < 3; i++){
            for (int j = 0; j < 3; j++){
                if (j!=1 || i != 1)
                    drawGasket(x + i * sub, y + j * sub, sub);
            }
        }
    }
}
public void拉丝垫片(内部x、内部y、内部侧){
int sub=侧面/3;
//画中心广场
g2d.fill(新的矩形2d.Double(x+sub,y+sub,sub-1,sub-1));
如果(子>=3){
//画8个周围的正方形
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
如果(j!=1 | i!=1)
拉丝垫片(x+i*sub,y+j*sub,sub);
}
}
}
}
堆栈实现:

    public void stack (int x, int y, int side ){
    GenericStack<Integer> s = new GenericStack<>();

    int sub = side /3;
    g2d.fill(new Rectangle2D.Double(x + sub, y + sub, sub - 1, sub - 1));

    while (!s.isEmpty()){
        x=s.pop();
        if (sub >=3){
            for (int i = 0; i < 3; i++){
                for (int j = 0; j < 3; j++){    
                    if (j!=1 || i != 1){
                        int operation = x+i*sub;
                        s.push(operation);
                        int operation2 = y+j*sub;
                        s.push(operation2);
                        s.push(sub);
                    }
                }
            }
        }
    }
}
公共无效堆栈(int x、int y、int侧){
GenericStack s=新的GenericStack();
int sub=侧面/3;
g2d.fill(新的矩形2d.Double(x+sub,y+sub,sub-1,sub-1));
而(!s.isEmpty()){
x=s.pop();
如果(子>=3){
对于(int i=0;i<3;i++){
对于(int j=0;j<3;j++){
如果(j!=1 | i!=1){
整数运算=x+i*sub;
s、 推(操作);
int操作2=y+j*子;
s、 推动(操作2);
s、 推(分);
}
}
}
}
}
}
我的堆栈类:

public class GenericStack<T> {

private int size; // size
private Node<T> head; // node head

public GenericStack() { // constructor
    head = null; // head is null
    size = 0; // size is zero
}

public void push(T element) {
    if(head == null) { // if head is null
        head = new Node(element); // head is node 
    } else {
        Node<T> newNode = new Node(element);
        newNode.next = head;
        head = newNode;
    }

    size++;
}

public T pop() {
    if(head == null)
        return null;
    else {
        T topData = head.data;

        head = head.next;
        size--;

        return topData;
    }
}

public T top() {
    if(head != null)
        return head.data;
    else
        return null;
}

public int size() {
    return size;
}

public boolean isEmpty() {
    return size == 0;
}

private class Node<T> {
    private T data;
    private Node<T> next;

    public Node(T data) {
        this.data = data;
    }

}
public类GenericStack{
私有整数大小;//大小
私有节点头;//节点头
公共GenericStack(){//构造函数
head=null;//head为null
size=0;//大小为零
}
公共无效推送(T元素){
if(head==null){//if head为null
head=新节点(元素);//head是节点
}否则{
节点newNode=新节点(元素);
newNode.next=头部;
头=新节点;
}
大小++;
}
公共广播电台{
if(head==null)
返回null;
否则{
T topData=head.data;
head=head.next;
大小--;
返回topData;
}
}
公共T top(){
if(head!=null)
返回头数据;
其他的
返回null;
}
公共整数大小(){
返回大小;
}
公共布尔值为空(){
返回大小==0;
}
私有类节点{
私有T数据;
私有节点下一步;
公共节点(T数据){
这个数据=数据;
}
}

如果您可以将递归版本描述为已经基于堆栈,那么您应该能够适当地翻译代码。如果您认为对
DrawShippet(x+i*sub,y+j*sub,sub)的每次递归调用;
都是将三个值推到堆栈上,并且每个第一步都是“内部”的
DrawShippet
方法是从堆栈中弹出三个值,然后在迭代解决方案中显式地在GenericStack上下弹出这些相同的值,应该遵循相同的模式。基本上,就像在递归解决方案中一样,您需要在堆栈上推、推、推连续的值,直到val用完使用push;然后需要从堆栈中弹出、弹出、弹出连续值并“绘制”一个适合于刚刚弹出的值的矩形,直到堆栈为空。

如果您可以将递归版本描述为已经基于堆栈,那么您应该能够适当地转换代码。如果您想到对
DrawShippet的每个递归调用(x+i*sub,y+j*sub,sub)
将三个值推到一个堆栈上,并且每个第一步都“在内部”
DrawShippet
方法是从堆栈中弹出三个值,然后在迭代解决方案中显式地在GenericStack上下弹出这些相同的值,应该遵循相同的模式。基本上,就像在递归解决方案中一样,您需要在堆栈上推、推、推连续的值,直到val用完ues推送;然后需要从堆栈中弹出、弹出、弹出连续的值,并“绘制”一个与刚刚弹出的值相匹配的矩形,直到堆栈为空。

我没有看到问题。问题(据我所知)是“如何编写我已经编写的递归解决方案的迭代(基于堆栈的)版本?”我没有看到一个问题。问题(据我所知)是“如何编写我已经编写的递归解决方案的迭代(基于堆栈)版本?”因此,当我弹出该方法时,我是否在while循环的开始处执行该操作,对于递归参数,我是否逐个推送它们?我认为您将需要两个while循环,一个用于推送,一个用于弹出。
while(仍有项要推送到堆栈上)
while(仍有项要从堆栈中弹出)
。是的,您需要按正确顺序逐个推送项目,然后按“相反顺序”逐个弹出。因此,当我弹出该方法时,我是否在while循环的开始处执行该操作,对于递归参数,我是否逐个推送它们?我认为您将需要两个while循环,一个用于推送,一个用于弹出。
while(仍有项要推送到堆栈上)
while(仍有项要从堆栈中弹出)
。是的,您需要按正确顺序逐个推送项目,然后按“相反顺序”逐个弹出。