最近在劍指Offer上刷了一些題目,發現涉及到數據結構類的題目,如果想在本地IDE進行測試,除了完成題目要求的算法外,還需要寫一些輔助函數,比如樹的創建,遍歷等,由於這些函數平時用到的地方比較多,並且也能加深對常用數據結構的理解,這里將Leetcode中與樹(TreeNode)相關題目會用到的測試輔助函數做一個總結。
代碼文件說明
- LeetCode.java 劍指Offer在線編程中關於樹的數據結構定義
- TreeHelper.java: 主要是和樹相關的常用操作函數,包括:二叉樹的創建、三種遍歷、獲取樹的節點數,高度、判斷是否為二叉搜索樹,以及搜索二叉樹的創建、插入、刪除
- TreeHelperTest.java: 主要用來對TreeHelper.java中的函數進行測試
- Solution18.java:LeetCode 劍指Offer在線編程第18道題"二叉樹的鏡像"題解,和本地測試方法
源代碼
1.TreeNode.java
package structure;
public class TreeNode {
public int val = 0;
public TreeNode left = null;
public TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
2.TreeHelper.java
package structure;
import static java.lang.Math.max;
public class TreeHelper {
static int index;
static String[] values;
public TreeHelper(){}
// 根據形如”1,2,#,4,5,#,7,#“的字符串建立二叉樹,其中#代表該節點為空
public void setValues(String treeValues) {
values = treeValues.split(",");
index = 0;
}
// 遞歸建立二叉樹
public TreeNode createTree() {
TreeNode node = null;
if(index < values.length){
if (values[index].equals("#")) {
index++;
return null;
}
node = new TreeNode(Integer.parseInt(values[index]));
index++;
node.left = createTree();
node.right = createTree();
}
return node;
}
//前序遍歷
public void preOrder(TreeNode root) {
if (root == null) {
return;
} else {
System.out.print(root.val + " ");
preOrder(root.left);
preOrder(root.right);
}
}
//中序遍歷
public void inOrder(TreeNode root) {
if (root == null) {
return;
} else {
preOrder(root.left);
System.out.print(root.val + " ");
preOrder(root.right);
}
}
//后序遍歷
public void postOrder(TreeNode root) {
if (root == null) {
return;
} else {
preOrder(root.left);
preOrder(root.right);
System.out.print(root.val + " ");
}
}
//獲取二叉樹的節點個數
public int getNodeNum(TreeNode root) {
if (root == null) {
return 0;
}
return 1 + getNodeNum(root.left) + getNodeNum(root.right);
}
//獲取二叉樹的高度
public int getTreeHeight(TreeNode root) {
if (root == null) {
return 0;
}
return 1 + max(getTreeHeight(root.left), getTreeHeight(root.right));
}
//創建二叉搜索樹BST
public TreeNode createSearchTree(int[] treeValues){
TreeNode rootBST = null;
for (int value : treeValues) {
rootBST = insertNode(rootBST,value);
}
return rootBST;
}
//判斷一個二叉樹是否為二叉搜索樹,時間復雜度O(1)
public boolean isBST(TreeNode root) {
return isBSTResolve(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public boolean isBSTResolve(TreeNode root, int min, int max) {
if (root == null) {
return true;
}
if (root.val < min || root.val > max) {
return false;
}
return isBSTResolve(root.left, min, root.val) && isBSTResolve(root.right, root.val, max);
}
//根據值查找二叉樹搜索樹root的某個節點
public TreeNode findNode(TreeNode rootBST, int val) {
if (rootBST == null) {
return null;
} else if (rootBST.val < val) {
return findNode(rootBST.right, val);
} else if (rootBST.val > val) {
return findNode(rootBST.left, val);
}
return rootBST;
}
//向二叉搜索樹中插入值val
public TreeNode insertNode(TreeNode rootBST, int val) {
if (rootBST == null) {
rootBST = new TreeNode(val);
} else {
if (val < rootBST.val) {
rootBST.left = insertNode(rootBST.left, val);
} else if (val > rootBST.val) {
rootBST.right = insertNode(rootBST.right, val);
}
}
return rootBST;
}
//刪除二叉樹中某個值為val的節點
public TreeNode deleteNode(TreeNode rootBST, int val) {
if (findNode(rootBST, val) == null) {
System.out.println("要刪除的節點不存在!");
} else {
if (val < rootBST.val) {
rootBST.left = deleteNode(rootBST.left, val);
} else if (val > rootBST.val) {
rootBST.right = deleteNode(rootBST.right, val);
} else { //rootBST就是要被刪除的節點
if (rootBST.left != null && rootBST.right != null) { //被刪除的節點的左右子節點均存在
TreeNode tmp = findMinNode(rootBST.right); //從右子樹找到值最小的節點填充刪除節點
rootBST.val = tmp.val;
rootBST.right = deleteNode(rootBST.right, rootBST.val); //刪除右子樹值最小的元素
} else { //被刪除的節點只有一個或者無子節點存在
//被刪除節點的左子節點為空,則右子節點取代根節點
if (rootBST.left == null) {
rootBST = rootBST.right;
} else {
rootBST = rootBST.left;
}
}
}
}
return rootBST;
}
// 找到二叉搜索樹中值最小的節點
public TreeNode findMinNode(TreeNode rootBST) {
if (rootBST == null) {
return null;
} else if (rootBST.left == null) {
return rootBST;
}
return findMinNode(rootBST.left);
}
}
3.TreeHelperTest.java
package test;
import structure.TreeHelper;
import structure.TreeNode;
class treeHelperTest {
public static void main(String[] args) {
String treeNodeValues = "1,2,#,#,3,4,#,#,5,6,#,8,#,#";
TreeHelper treeHelper = new TreeHelper();
treeHelper.setValues(treeNodeValues);
try {
TreeNode root = treeHelper.createTree();
System.out.println("創建二叉樹成功!");
System.out.println("前序遍歷二叉樹:");
treeHelper.preOrder(root);
System.out.println();
System.out.println("中序遍歷二叉樹:");
treeHelper.inOrder(root);
System.out.println();
System.out.println("后序遍歷二叉樹:");
treeHelper.postOrder(root);
System.out.println();
System.out.printf("二叉樹的節點數目:%d\n", treeHelper.getNodeNum(root));
System.out.printf("二叉樹的高度:%d\n", treeHelper.getTreeHeight(root));
System.out.println("二叉樹是否為二叉搜索樹:" + String.valueOf(treeHelper.isBST(root)));
} catch (Exception e) {
e.printStackTrace();
}
try {
TreeNode rootBST = treeHelper.createSearchTree(new int[]{2, 4, 3, 1, 9, 7, 6, 8});
System.out.println("創建二叉搜索樹成功!");
System.out.println("二叉樹是否為二叉搜索樹:" + String.valueOf(treeHelper.isBST(rootBST)));
System.out.println("中序遍歷二叉搜索樹:");
treeHelper.inOrder(rootBST);
System.out.println();
rootBST = treeHelper.insertNode(rootBST, 5);
System.out.println("中序遍歷插入5后的二叉搜索樹:");
treeHelper.inOrder(rootBST);
System.out.println();
rootBST = treeHelper.deleteNode(rootBST, 6);
System.out.println("中序遍歷刪除6后的二叉搜索樹:");
treeHelper.inOrder(rootBST);
System.out.println();
} catch (Exception e) {
e.printStackTrace();
}
}
}
測試結果如下

4.劍指Offer在線編程第18道題"二叉樹的鏡像"

Solution18
import structure.TreeHelper;
import structure.TreeNode;
/*
* Q:操作給定的二叉樹,將其變換為源二叉樹的鏡像
* tag: 樹
*/
public class Solution18 {
public static void main(String[] args) {
Solution18 s = new Solution18();
s.testMirror();
}
public void Mirror(TreeNode root) {
if(root == null){
return;
}
if(root.left == null){
root.left = root.right;
root.right = null;
Mirror(root.left);
}
else if(root.right == null){
root.right = root.left;
root.left = null;
Mirror(root.right);
}
else{
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
Mirror(root.right);
Mirror(root.left);
}
}
public void testMirror(){
TreeHelper treeHelper = new TreeHelper();
String treeValues = "1,2,#,#,3,4,#,#,5,6,#,8,#,#";
treeHelper.setValues(treeValues);
TreeNode root = treeHelper.createTree();
System.out.println("中序遍歷二叉樹:");
treeHelper.inOrder(root);
System.out.println();
Mirror(root);
System.out.println("中序遍歷二叉樹的鏡像:");
treeHelper.inOrder(root);
System.out.println();
}
}
運行結果如下:

