使用D中的指针实现递归函数

时间:2014-06-11 04:31:23

标签: pointers recursion d

我目前正在尝试实现一个从数字列表构建树的递归函数。我目前有这个:

Node makelist(Integer[] nums) {
  if (nums.length == 1) {
    return Node(nums[0]);
  } else {
    Integer half = nums.length/2;
    return Node(makelist(nums[0..half]), makelist(nums[half..$]));
  }
}

这对我来说很好,而Node是一个对象。但是,我希望Node成为一个结构。结果,我为Node编写了以下代码:

struct Node {
  Node* left, right, parent;
  Integer val;

  this(Integer val) {
    this.val = val;
  }

  this(Node* left, Node* right) {
    this.left = left;
    this.right = right;
    val = min(left.val, right.val);
    left.parent = &this;
    right.parent = &this;
  }
}

现在,编译器显然不太喜欢这个。但是,我不知道如何获取任何makelist返回的地址,以使构造函数的参数成为指针。基本上,我想要将ref Node传递为leftright(但编译器也在这里婊子)或指针(但我似乎无法获得那些工作要么)。

我是低级代码的新手,并希望得到一些帮助,让它工作。基本上,我想使用上面描述的递归makelist,并且有Node个的两个构造函数。我怎么能这样做并保持Node结构?

2 个答案:

答案 0 :(得分:4)

我不确定你到底想要什么,但是这个:

import std.stdio;
import std.algorithm;

alias Integer = size_t;

alias Node = _Node*;

struct _Node {
    Node left, right, parent;
    Integer val;

    this(Integer val) {
        this.val = val;
    }

    this(Node left, Node right) {
        this.left = left;
        this.right = right;
        val = min(left.val, right.val);
        left.parent = &this;
        right.parent = &this;
    }
}

Node makelist(Integer[] nums) {
    if (nums.length == 1) {
        return new _Node(nums[0]);
    } else {
        Integer half = nums.length/2;
        return new _Node(makelist(nums[0..half]), makelist(nums[half..$]));
    }
}

答案 1 :(得分:2)

另一种方法是使用别名

import std.stdio;
import std.algorithm;
import core.stdc.string;

alias Integer = size_t;

struct Node {
    alias me this;
    @property Node* me() {
        Node* n = new Node();
        memcpy(cast(void*)n, cast(void*)&this, this.sizeof);
        return n;
    }

    Node * left, right, parent;
    Integer val;

    this(Integer val) {
        this.val = val;
    }

    this(Node left, Node right) {
        this.left = left;
        this.right = right;
        val = min(left.val, right.val);
        left.parent = right.parent = &this;
    }
}

Node makelist(Integer[] nums) {
    if (nums.length == 1) {
        return Node(nums[0]);
    } else {
        Integer half = nums.length/2;
        return Node(makelist(nums[0..half]), makelist(nums[half..$]));
    }
}