Algorithm 查找数组表示的2 BST是否同构

Algorithm 查找数组表示的2 BST是否同构,algorithm,tree,binary-search-tree,Algorithm,Tree,Binary Search Tree,1) 给定包含完整二叉树元素的两个数组(逐级),而不实际重建树(即仅在数组中进行交换),如何确定这两个数组是否同构 2) 如果一棵同构树形成一棵二叉搜索树,则是更好的解决方案 更新例如 5 / \ 4 7 /\ /\ 2 3 6 8 可以在数组中表示为5 4 7 2 3 6 8 同构树是可以通过围绕节点旋转而相互转换的树 5 / \ 4 7 /\ /\ 2 3 6 8 5 / \

1) 给定包含完整二叉树元素的两个数组(逐级),而不实际重建树(即仅在数组中进行交换),如何确定这两个数组是否同构

2) 如果一棵同构树形成一棵二叉搜索树,则是更好的解决方案

更新例如

     5 
    / \
    4  7
   /\  /\
  2  3 6 8
可以在数组中表示为
5 4 7 2 3 6 8

同构树是可以通过围绕节点旋转而相互转换的树

     5 
    / \
    4  7
   /\  /\
  2  3 6 8



     5 
    / \
    4  7
   /\  /\
  3  2 6 8



     5 
    / \
    4  7
   /\  /\
  3  2 8 6



     5 
    / \
    7  4
   /\  /\
  8  6 3 2

您可以同时对这两个节点执行顺序树漫游,并检查它们的元素是否相同。

您可以同时对这两个节点执行顺序树漫游,并检查它们的元素是否相同。

首先参与(2)在每个级别交换节点对及其子节点,如有必要将每棵树转换为二元搜索树,左节点首先参与(2),在每个级别交换节点对-及其后代,如有必要将每棵树转换为二元搜索树,左节点用于第一个问题:

一点符号:

  • t0,t1-树
  • 值(t)-存储在节点上的数字
  • 左(t)-左子树
  • 右(t)-右子树
t1
t2
是同构的,iff
t1
t2
为空

值(t1)=值(t2)

left(t1)
left(t2)
同构,
right(t1)
right(t2)
同构

或者
left(t1)
right(t2)
同构,
right(t1)
left(t2)

假设树存储在数组中,元素0是根,如果
t
是内部节点的索引
2t+1
2t+2
是其直接子节点的索引,则直接实现:

#include <stdio.h>

#define N 7

int a[] = { 5, 4, 7, 2, 3, 6, 8 };
int b[] = { 5, 7, 4, 6, 8, 2, 3 };

int
is_isomorphic (int t1, int t2)
{
  if (t1 >= N && t2 >= N)
    return 1;

  if (a [t1] != b [t2])
    return 0;

  return ((is_isomorphic (2*t1 + 1, 2*t2 + 1)
           && is_isomorphic (2*t1 + 2, 2*t2 + 2))
          || (is_isomorphic (2*t1 + 1, 2*t2 + 2)
              && is_isomorphic (2*t1 + 2, 2*t2 + 1)));
}

int main ()
{
  printf ("%s\n", (is_isomorphic (0, 0) ? "yes" : "no"));
  return 0;
}
关于第一个问题:

一点符号:

  • t0,t1-树
  • 值(t)-存储在节点上的数字
  • 左(t)-左子树
  • 右(t)-右子树
t1
t2
是同构的,iff
t1
t2
为空

值(t1)=值(t2)

left(t1)
left(t2)
同构,
right(t1)
right(t2)
同构

或者
left(t1)
right(t2)
同构,
right(t1)
left(t2)

假设树存储在数组中,元素0是根,如果
t
是内部节点的索引
2t+1
2t+2
是其直接子节点的索引,则直接实现:

#include <stdio.h>

#define N 7

int a[] = { 5, 4, 7, 2, 3, 6, 8 };
int b[] = { 5, 7, 4, 6, 8, 2, 3 };

int
is_isomorphic (int t1, int t2)
{
  if (t1 >= N && t2 >= N)
    return 1;

  if (a [t1] != b [t2])
    return 0;

  return ((is_isomorphic (2*t1 + 1, 2*t2 + 1)
           && is_isomorphic (2*t1 + 2, 2*t2 + 2))
          || (is_isomorphic (2*t1 + 1, 2*t2 + 2)
              && is_isomorphic (2*t1 + 2, 2*t2 + 1)));
}

int main ()
{
  printf ("%s\n", (is_isomorphic (0, 0) ? "yes" : "no"));
  return 0;
}
对于英国夏令时:

  • 取两个数组的第一个元素并匹配。如果不相等,则BST不相同。
  • 找到未扫描的第一个左子项(在leftPos1和leftPos2位置)并匹配。如果不匹配,则BST不相同。
  • 找到未扫描的第一个右子项(在位置rightPos1和rightPos2处)并匹配。如果不匹配,则BST不相同。
  • 如果左和右子级都匹配,则在两对子列表/子树(来自leftPos1和leftPos2)和(来自rightPos1和rightPos2)上递归执行相同的操作。这些子树的父元素是数组的第一个元素。 在子列表中搜索左侧和右侧子项时,可能存在已扫描的元素。要查找此类元素,请验证该元素是否可以是当前子树的子元素。如果当前子树位于父元素的左侧,则将该元素与父元素进行比较,如果它属于右侧,则忽略该元素

    #include <stdio.h>
    
    #define BOOL int
    #define TRUE 1
    #define FALSE 0
    
    BOOL isLeft(int parent, int child) {
        return child <= parent;
    }
    
    BOOL isRight(int parent, int child) {
        return child > parent;
    }
    
    BOOL isBelongToChild(int parent, int child, int value) {
        if (isLeft(parent, child) && (isLeft(parent, value))) {
            return TRUE;
        }
        if (isRight(parent, child) && (isRight(parent, value))) {
            return TRUE;
        }
        return FALSE;
    }
    
    int getLeftPosition(int * array, int size, int parent, BOOL parentExists) {
        int i;
    
        int first = *array;
        for (i = 1; i < size; i++) {
            int value = *(array + i);
            if (! isBelongToChild(parent, first, value)) {
                continue;
            }
            if (isLeft(first, value)) {
                return i;
            }
        }
        return -1;
    }
    
    int getRightPosition(int * array, int size, int parent, BOOL parentExists) {
        int i;
    
        int first = *array;
        for (i = 1; i < size; i++) {
            int value = *(array + i);
            if (! isBelongToChild(parent, first, value)) {
                continue;
            }
            if (isRight(first, value)) {
                return i;
            }
        }
        return -1;
    }
    
    BOOL areSame(int * array1, int pos1, int * array2, int pos2) {
        if (pos1 == -1 && pos2 == -1) {
            return TRUE;
        } else if (*(array1 + pos1) == *(array2 + pos2)) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
    
    BOOL isSameBst(int * array1, int size1, int * array2, int size2, int parent, BOOL parentExists) {
        if (0 == size1 && 0 == size2) {
            return TRUE;
        }
        if (*array1 != *array2) {
            return FALSE;
        }
    
        int leftPos1 = getLeftPosition(array1, size1, parent, parentExists);
        int leftPos2 = getLeftPosition(array2, size2, parent, parentExists);
        if (! areSame(array1, leftPos1, array2, leftPos2)) {
            return FALSE;
        }
        int rightPos1 = getRightPosition(array1, size1, parent, parentExists);
        int rightPos2 = getRightPosition(array2, size2, parent, parentExists);
        if (! areSame(array1, rightPos1, array2, rightPos2)) {
            return FALSE;
        }
    
        if (leftPos1 > -1) {
            int result = isSameBst((array1 + leftPos1), size1 - leftPos1, (array2 + leftPos2), size2 - leftPos2, *array1, TRUE);
            if (FALSE == result) {
                return FALSE;
            }
        }
        if (rightPos1 > -1) {
            int result = isSameBst((array1 + rightPos1), size1 - rightPos1, (array2 + rightPos2), size2 - rightPos2, *array1, TRUE);
            if (FALSE == result) {
                return FALSE;
            }
        }
        return TRUE;
    }
    
    int main ()
    {
        int a[] = { 5, 6, 2, 7, 4 };
        int b[] = { 5, 6, 7, 2, 4 };
        printf ("%s\n", (isSameBst(a, 5, b, 5, 0, FALSE) ? "yes" : "no"));
        return 0;
    }
    
    #包括
    #定义布尔整数
    #定义真1
    #定义FALSE 0
    布尔isLeft(整数父级,整数子级){
    返回子女父母;
    }
    BOOL isBelongToChild(int父项、int子项、int值){
    if(isLeft(父,子)和&(isLeft(父,值))){
    返回TRUE;
    }
    if(isRight(父项,子项)&(isRight(父项,值))){
    返回TRUE;
    }
    返回FALSE;
    }
    int getLeftPosition(int*数组、int大小、int父级、BOOL父级存在){
    int i;
    int first=*数组;
    对于(i=1;i