如何在内存中表示Pascal-esque(等边)三角形

时间:2012-11-05 14:08:27

标签: data-structures tree

我正在处理Project Euler Problem 18(我做了解决问题;我不是在作弊。“Proof”在这里“并发现自己需要一种方法表示看起来像Pascal三角形但具有不同值的数据结构。它看起来非常类似于二叉树,但有一个非常重要的区别:节点的子节点不仅仅是它的子节点。所以前三行看起来像这样:

    75
   /  \
  95  64
 /  \ / \
17  47  82

请注意,47有两个父母。

很容易将它表示为链接结构,甚至是二维数组,但我希望有一种更优雅的方式。我喜欢二叉树,主要是因为你可以如何分配一块内存,将它视为一个数组,并且通过几个算术运算或整数除法在子项和父项之间导航。 有没有办法对此数据结构执行相同操作?

我最好的解决方案是使用二维数组(在那里很容易找到孩子和父母)。我不喜欢这个实现,因为(至少我这样做了)我为每一行调用malloc,尽管我知道结构会提前有多大。

我的问题与this one非常相似,但我对接受的答案不满意。评论提到我寻求的解决方案,但没有给出解释。

编辑:为了澄清,我正在寻找一种方法索引到一维数组,就像二进制树顺序填充到数组中一样(从1开始)给出索引 i 的节点的子节点位于索引2 * i 和2 * i + 1的属性我也不太关心能找到父母,所以不要太担心这对奇怪的双亲。

2 个答案:

答案 0 :(得分:1)

是的,可以在一维数组中存储三角形数据结构(例如Java):

class Triangle<T> {
  private T[] triangle;

  public Triangle(T[] array, int rows) {
    if (array.length != triangleNumber(rows)) {
      throw new IllegalArgumentException("Array wrong size");
    }
    triangle = array;
  }

  public T get(int row, int col) {
    return triangle[index(row, col)];
  }

  public void set(int row, int col, T val) {
    triangle[index(row, col)] = val; 
  }

  private int triangleNumber(int rows) {
    return rows * (rows + 1) / 2;
  }

  private int index(int row, int col) {
    if (row < 0 || col < 0 || col > row) {
      throw new IndexOutOfBoundsException("Trying to access outside of triangle");
    }
    return triangleNumber(row) + col;
  }
}

传递给构造函数的数组是通过将三角形的行逐个连接到数组中形成的:[t(0,0),t(1,0),t(1,1),t (2,0),t(2,1),t(2,2),...,t(行-1,行-1)],其中t(R,C)是三角形行的三角形单元格R和三角形列C.

对于任何单元格(row,col):

  • 左子将在行+ 1,col
  • 正确的孩子将在第+行,第1行,第1行
  • 左父母将在第1行,第1行
  • 右父母将在第1行,col

所有细胞都不存在两个父母和两个孩子,因为他们会位于三角形之外。请参阅索引方法中的异常检查。

答案 1 :(得分:0)

是的,有: 我们从你对二维数组的想法开始,但行长度不规则。所以每个元素都用一个二维索引(r,c)索引;         (1,1)      (2,1)(2,2)    (3,1)(3,2)(3,3) (4,1)(4,2)(4,3)(4,4)

因为这种关系是正常的,你可以表达我们的立场:
对于节点(r,c),子节点是(r + 1,min(1,c)),(r + 1,max(c + 1,r)),他的父节点是:(r-1,min( 1,C-1)),(R-1,MAX(C,R))