diff --git a/codes/javascript/chapter_tree/binary_search_tree.js b/codes/javascript/chapter_tree/binary_search_tree.js index 38a917e16..254eb5ade 100644 --- a/codes/javascript/chapter_tree/binary_search_tree.js +++ b/codes/javascript/chapter_tree/binary_search_tree.js @@ -56,7 +56,7 @@ class BinarySearchTree { else cur = cur.left; } // 插入节点 - let node = new TreeNode(num); + const node = new TreeNode(num); if (pre.val < num) pre.right = node; else pre.left = node; } @@ -82,7 +82,7 @@ class BinarySearchTree { // 子节点数量 = 0 or 1 if (cur.left === null || cur.right === null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 - let child = cur.left !== null ? cur.left : cur.right; + const child = cur.left !== null ? cur.left : cur.right; // 删除节点 cur if (cur !== this.root) { if (pre.left === cur) pre.left = child; @@ -119,7 +119,7 @@ console.log('\n初始化的二叉树为\n'); printTree(bst.getRoot()); /* 查找节点 */ -let node = bst.search(7); +const node = bst.search(7); console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + node.val); /* 插入节点 */ diff --git a/codes/typescript/chapter_tree/avl_tree.ts b/codes/typescript/chapter_tree/avl_tree.ts index 3aea7d1e8..812fe4a03 100644 --- a/codes/typescript/chapter_tree/avl_tree.ts +++ b/codes/typescript/chapter_tree/avl_tree.ts @@ -10,7 +10,7 @@ import { printTree } from '../modules/PrintUtil'; /* AVL 树*/ class AVLTree { root: TreeNode; - /*构造方法*/ + /* 构造方法 */ constructor() { this.root = null; //根节点 } @@ -218,3 +218,5 @@ testRemove(avlTree, 4); // 删除度为 2 的节点 /* 查询节点 */ const node = avlTree.search(7); console.log('\n查找到的节点对象为', node, ',节点值 = ' + node.val); + +export {}; diff --git a/codes/typescript/chapter_tree/binary_search_tree.ts b/codes/typescript/chapter_tree/binary_search_tree.ts index de8393095..248c7b5a1 100644 --- a/codes/typescript/chapter_tree/binary_search_tree.ts +++ b/codes/typescript/chapter_tree/binary_search_tree.ts @@ -8,159 +8,136 @@ import { TreeNode } from '../modules/TreeNode'; import { printTree } from '../modules/PrintUtil'; /* 二叉搜索树 */ -let root: TreeNode | null; +class BinarySearchTree { + private root: TreeNode | null; -function BinarySearchTree(nums: number[]): void { - nums.sort((a, b) => a - b); // 排序数组 - root = buildTree(nums, 0, nums.length - 1); // 构建二叉搜索树 -} - -/* 获取二叉树根节点 */ -function getRoot(): TreeNode | null { - return root; -} + /* 构造方法 */ + constructor() { + // 初始化空树 + this.root = null; + } -/* 构建二叉搜索树 */ -function buildTree(nums: number[], i: number, j: number): TreeNode | null { - if (i > j) { - return null; + /* 获取二叉树根节点 */ + getRoot(): TreeNode | null { + return this.root; } - // 将数组中间节点作为根节点 - let mid = Math.floor((i + j) / 2); - let root = new TreeNode(nums[mid]); - // 递归建立左子树和右子树 - root.left = buildTree(nums, i, mid - 1); - root.right = buildTree(nums, mid + 1, j); - return root; -} -/* 查找节点 */ -function search(num: number): TreeNode | null { - let cur = root; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - if (cur.val < num) { - cur = cur.right; // 目标节点在 cur 的右子树中 - } else if (cur.val > num) { - cur = cur.left; // 目标节点在 cur 的左子树中 - } else { - break; // 找到目标节点,跳出循环 + /* 查找节点 */ + search(num: number): TreeNode | null { + let cur = this.root; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 目标节点在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 目标节点在 cur 的左子树中 + else if (cur.val > num) cur = cur.left; + // 找到目标节点,跳出循环 + else break; } + // 返回目标节点 + return cur; } - // 返回目标节点 - return cur; -} -/* 插入节点 */ -function insert(num: number): void { - // 若树为空,则初始化根节点 - if (root === null) { - root = new TreeNode(num); - return; - } - let cur = root, - pre: TreeNode | null = null; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - if (cur.val === num) { - return; // 找到重复节点,直接返回 + /* 插入节点 */ + insert(num: number): void { + // 若树为空,则初始化根节点 + if (this.root === null) { + this.root = new TreeNode(num); + return; } - pre = cur; - if (cur.val < num) { - cur = cur.right as TreeNode; // 插入位置在 cur 的右子树中 - } else { - cur = cur.left as TreeNode; // 插入位置在 cur 的左子树中 + let cur: TreeNode | null = this.root, + pre: TreeNode | null = null; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 找到重复节点,直接返回 + if (cur.val === num) return; + pre = cur; + // 插入位置在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 插入位置在 cur 的左子树中 + else cur = cur.left; } + // 插入节点 + const node = new TreeNode(num); + if (pre!.val < num) pre!.right = node; + else pre!.left = node; } - // 插入节点 - let node = new TreeNode(num); - if (pre!.val < num) { - pre!.right = node; - } else { - pre!.left = node; - } -} -/* 删除节点 */ -function remove(num: number): void { - // 若树为空,直接提前返回 - if (root === null) { - return; - } - let cur = root, - pre: TreeNode | null = null; - // 循环查找,越过叶节点后跳出 - while (cur !== null) { - // 找到待删除节点,跳出循环 - if (cur.val === num) { - break; + /* 删除节点 */ + remove(num: number): void { + // 若树为空,直接提前返回 + if (this.root === null) return; + let cur: TreeNode | null = this.root, + pre: TreeNode | null = null; + // 循环查找,越过叶节点后跳出 + while (cur !== null) { + // 找到待删除节点,跳出循环 + if (cur.val === num) break; + pre = cur; + // 待删除节点在 cur 的右子树中 + if (cur.val < num) cur = cur.right; + // 待删除节点在 cur 的左子树中 + else cur = cur.left; } - pre = cur; - if (cur.val < num) { - cur = cur.right as TreeNode; // 待删除节点在 cur 的右子树中 - } else { - cur = cur.left as TreeNode; // 待删除节点在 cur 的左子树中 - } - } - // 若无待删除节点,则直接返回 - if (cur === null) { - return; - } - // 子节点数量 = 0 or 1 - if (cur.left === null || cur.right === null) { - // 当子节点数量 = 0 / 1 时, child = null / 该子节点 - let child = cur.left !== null ? cur.left : cur.right; - // 删除节点 cur - if (cur != root) { - if (pre!.left === cur) { - pre!.left = child; + // 若无待删除节点,则直接返回 + if (cur === null) return; + // 子节点数量 = 0 or 1 + if (cur.left === null || cur.right === null) { + // 当子节点数量 = 0 / 1 时, child = null / 该子节点 + const child: TreeNode | null = cur.left !== null ? cur.left : cur.right; + // 删除节点 cur + if (cur !== this.root) { + if (pre!.left === cur) pre!.left = child; + else pre!.right = child; } else { - pre!.right = child; + // 若删除节点为根节点,则重新指定根节点 + this.root = child; } - } else { - // 若删除节点为根节点,则重新指定根节点 - root = child; } - } - // 子节点数量 = 2 - else { - // 获取中序遍历中 cur 的下一个节点 - let tmp = cur.right; - while (tmp.left !== null) { - tmp = tmp.left; + // 子节点数量 = 2 + else { + // 获取中序遍历中 cur 的下一个节点 + let tmp: TreeNode | null = cur.right; + while (tmp!.left !== null) { + tmp = tmp!.left; + } + // 递归删除节点 tmp + this.remove(tmp!.val); + // 用 tmp 覆盖 cur + cur.val = tmp!.val; } - // 递归删除节点 tmp - remove(tmp!.val); - // 用 tmp 覆盖 cur - cur.val = tmp.val; } } /* Driver Code */ /* 初始化二叉搜索树 */ -const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]; -BinarySearchTree(nums); +const bst = new BinarySearchTree(); +// 请注意,不同的插入顺序会生成不同的二叉树,该序列可以生成一个完美二叉树 +const nums = [8, 4, 12, 2, 6, 10, 14, 1, 3, 5, 7, 9, 11, 13, 15]; +for (const num of nums) { + bst.insert(num); +} console.log('\n初始化的二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); /* 查找节点 */ -let node = search(7); -console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + node!.val); +const node = bst.search(7); +console.log('\n查找到的节点对象为 ' + node + ',节点值 = ' + (node ? node.val : 'null')); /* 插入节点 */ -insert(16); +bst.insert(16); console.log('\n插入节点 16 后,二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); /* 删除节点 */ -remove(1); +bst.remove(1); console.log('\n删除节点 1 后,二叉树为\n'); -printTree(getRoot()); -remove(2); +printTree(bst.getRoot()); +bst.remove(2); console.log('\n删除节点 2 后,二叉树为\n'); -printTree(getRoot()); -remove(4); +printTree(bst.getRoot()); +bst.remove(4); console.log('\n删除节点 4 后,二叉树为\n'); -printTree(getRoot()); +printTree(bst.getRoot()); export {};