算法:二叉树的构建(TS实现)
需求:传入一个数组,将其构建成为一颗二叉树
算法思想:
- 用户传入一个空数组,或者传入其他非数组值,直接返回null,代表一颗空树
- 用户传入一个数组(数组长度大于等于1):将下标为0的节点作为根节点,其左孩子下标值为2n+1,右孩子下标值为2n+2,根节点下标为0,当左孩子还有孩子时,就将用户传入的数组和当前索引传入handleToNode,进行递归调用,直至递归到最后一层;如果当前孩子有右孩子也是同理;若当前节点没有左孩子或者右孩子,则直接返回null,这也是递归结束的条件。
代码结构如下:
首先看一下二叉树中每个节点的结构:
class TreeNode<TreeType>{
value:TreeType | null; //节点的值
leftChild:TreeNode<TreeType> | null; //左孩子
rightChild:TreeNode<TreeType> | null; //右孩子
constructor(value:TreeType | null){
this.value = value; //初始化节点值
this.leftChild = null; //初始化左孩子
this.rightChild = null;// 初始化右孩子
}
}
数据结构如上图所示-----value用于存储节点的值,leftChild指向当前节点的左孩子,rightChild指向当前节点的右孩子,初始时,节点的左右孩子指针分别指为空。
节点的结构定义好了之后,开始写二叉树的构建算法:
这里我分成了两个方法:分别为buildBinaryTree、handleNode
其中buildBinaryTree做了两件事情:一是用来判断当前传入的数组是否合法,二是构建二叉树。做了一层最基本的条件判断与处理,即如果传入的参数有值就进行递归处理成二叉树,若无值则直接return null 返回空树。
handleNode是用来实现构建二叉树的细节,以及深层次的递归处理,需要两个参数分别为:要转化的数组和当前处理的节点索引。
下面是buildBinaryTree方法的具体实现:
function buildBinaryTree<TreeType>(initTree:(TreeType|null)[]):TreeNode<TreeType> | null {
// 当前节点的索引值为n 左孩子的索引值为2n+1 右孩子的索引值为2n+2 且索引从0开始 即根节点的索引值下标是0
if(initTree.length==0){
return null; //说明是一颗空树
}
return handleNode<TreeType>(initTree,0)
}
下面是handleNode方法的具体实现:
function handleNode<TreeType>(initTree: Array<TreeType | null>,index:number):TreeNode<TreeType> | null{
if(index>=initTree.length||initTree[index]==null) return null
const currentNode = new TreeNode<TreeType>(initTree[index])
currentNode.leftChild = handleNode(initTree,2*index+1)
currentNode.rightChild = handleNode(initTree,2*index+2)
return currentNode
}
假如我们传递的参数为:
const preBinaryTree :Array<Number|null> = [3,9,20,22,23,null,24,null,26]
buildBinaryTree(preBinaryTree)
下面真机运行一下:
实际生成的物理结构应该是这样的: