Data structures 如何在内存中表示帕斯卡式(等边)三角形

Data structures 如何在内存中表示帕斯卡式(等边)三角形,data-structures,tree,Data Structures,Tree,我当时正在研究(我解决了问题;我没有作弊。”“在这里),发现自己需要一种方法来表示一个看起来像Pascal三角形,但值不同的数据结构。它看起来非常类似于二叉树,但有一个非常重要的区别:节点的子节点并不仅仅是它的子节点。前三行是这样的: 75 / \ 95 64 / \ / \ 17 47 82 请注意,47有两个父母 很容易将其表示为链接结构,甚至是二维数组,但我希望有一种更优雅的方式。我喜欢二叉树,主要是因为您可以分配单个内存块,将其视为一个数组,并且通过两个算

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

    75
   /  \
  95  64
 /  \ / \
17  47  82
请注意,47有两个父母

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

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

我的问题非常类似于,但我对被接受的答案不满意。一篇评论暗示了我寻求的解决方案,但没有给出任何解释

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

是的,有: 我们从二维数组开始,但是行长度不规则,所以每个元素都由二维索引(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))

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

类三角形{
私人T[]三角;
公共三角形(T[]数组,int行){
if(array.length!=三角形编号(行)){
抛出新的IllegalArgumentException(“数组大小错误”);
}
三角形=数组;
}
公共T获取(整数行,整数列){
返回三角形[索引(行、列)];
}
公共无效集(整数行、整数列、T值){
三角形[索引(行、列)]=val;
}
私有整数三角形编号(整数行){
返回行*(行+1)/2;
}
专用整数索引(整数行,整数列){
如果(行<0 | |列<0 | |列>行){
抛出新的IndexOutOfBoundsException(“尝试访问三角形外部”);
}
返回三角形编号(行)+列;
}
}
传递给构造函数的数组是通过将三角形的行逐个连接到数组中形成的:[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处的三角形单元

对于任何单元格(行、列):

  • 左边的子项将位于第+1行,列
  • 右边的子项将位于第+1行,第+1列
  • 左父级将位于第1行第1列
  • 正确的父项将位于第1行,col

并非所有细胞都存在双亲和两个子细胞,因为它们位于三角形之外。请参阅index方法中的异常检查。

谢谢,但我希望摆脱二维数组。请看我的编辑。@Jay你是说只有一个索引的索引方法?是的,没错。我肯定这是一个愚蠢的区别,但我很好奇这是否可能。@jay,是的,但它不会是线性函数,因为在二叉树的情况下,据我所知,这不是一棵“树”,这是一个循环图。
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;
  }
}