实验一:BinaryTree
实验二:实现以下对二叉树的操作,public static 修饰,要求一次遍历效率
根据实验内容和要求,将自己实现的程序代码写在此处,分析算法的时间复杂度。
实验一:BinaryNode.java
```java
public class BinaryNode {
public T data;
public BinaryNode left;
public BinaryNode right;
public BinaryNode(T data) {
this.data = data;
this.left = null;
this.right = null;
}
}
```
SeqList.java
```java
public class SeqList {
private Object[] data;
private int size;
public SeqList(int capacity) {
this.data = new Object[capacity];
this.size = 0;
}
public SeqList(T[] array) {
this.data = array;
this.size = array.length;
}
public int size() {
return this.size;
}
public T get(int index) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Index out of range: " + index);
}
return (T) data[index];
}
public void set(int index, T value) {
if (index < 0 || index >= size) {
throw new IndexOutOfBoundsException("Index out of range: " + index);
}
data[index] = value;
}
public void add(T value) {
if (size == data.length) {
throw new RuntimeException("List is full");
}
data[size++] = value;
}
}
```
BinaryTree.java
```java
public class BinaryTree {
private BinaryNode root;
public BinaryTree() {
this.root = null;
}
public BinaryTree(BinaryNode root) {
this.root = root;
}
public BinaryNode getRoot() {
return this.root;
}
public void setRoot(BinaryNode root) {
this.root = root;
}
public BinaryTree create(SeqList inList, SeqList postList) {
if (inList.size() != postList.size()) {
throw new IllegalArgumentException("Input lists have different sizes");
}
return new BinaryTree<>(createHelper(inList, 0, inList.size() - 1, postList, 0, postList.size() - 1));
}
private BinaryNode createHelper(SeqList inList, int inStart, int inEnd, SeqList postList, int postStart, int postEnd) {
if (inStart > inEnd || postStart > postEnd) {
return null;
}
T rootData = postList.get(postEnd);
BinaryNode root = new BinaryNode<>(rootData);
int rootIndex = inList.size() - 1;
for (int i = inStart; i <= inEnd; i++) {
if (inList.get(i).equals(rootData)) {
rootIndex = i;
break;
}
}
int leftSize = rootIndex - inStart;
root.left = createHelper(inList, inStart, rootIndex - 1, postList, postStart, postStart + leftSize - 1);
root.right = createHelper(inList, rootIndex + 1, inEnd, postList, postStart + leftSize, postEnd - 1);
return root;
}
public void leaf() {
leafHelper(root);
}
private void leafHelper(BinaryNode node) {
if (node == null) {
return;
}
if (node.left == null && node.right == null) {
System.out.print(node.data + " ");
}
leafHelper(node.left);
leafHelper(node.right);
}
public BinaryNode parent(BinaryNode p) {
return parentHelper(root, p);
}
private BinaryNode parentHelper(BinaryNode node, BinaryNode p) {
if (node == null) {
return null;
}
if (node.left == p || node.right == p) {
return node;
}
BinaryNode leftResult = parentHelper(node.left, p);
if (leftResult != null) {
return leftResult;
}
return parentHelper(node.right, p);
}
}
```
TestBinaryTree.java
```java
public class TestBinaryTree {
public static void main(String[] args) {
// Create binary tree from inorder and postorder traversal sequences
SeqList inList = new SeqList<>(new Integer[]{4, 2, 5, 1, 6, 3, 7});
SeqList postList = new SeqList<>(new Integer[]{4, 5, 2, 6, 7, 3, 1});
BinaryTree tree = new BinaryTree<>();
tree = tree.create(inList, postList);
System.out.print("Inorder traversal: ");
inorder(tree.getRoot());
System.out.println();
System.out.print("Postorder traversal: ");
postorder(tree.getRoot());
System.out.println();
// Print leaf nodes
System.out.print("Leaf nodes: ");
tree.leaf();
System.out.println();
// Find parent node
BinaryNode node = tree.getRoot().left.right;
BinaryNode parent = tree.parent(node);
System.out.println("Parent of " + node.data + " is " + parent.data);
}
private static void inorder(BinaryNode node) {
if (node == null) {
return;
}
inorder(node.left);
System.out.print(node.data + " ");
inorder(node.right);
}
private static void postorder(BinaryNode node) {
if (node == null) {
return;
}
postorder(node.left);
postorder(node.right);
System.out.print(node.data + " ");
}
}
```
① create(SeqList
② leaf() 方法的时间复杂度为 O(n),其中 n 为二叉树的结点数。
③ parent(BinaryNode
实验二:
public class BinaryTree {
private T data;
private BinaryTree leftChild;
private BinaryTree rightChild;
public BinaryTree(T data) {
this.data = data;
this.leftChild = null;
this.rightChild = null;
}
public void setLeftChild(BinaryTree leftChild) {
this.leftChild = leftChild;
}
public void setRightChild(BinaryTree rightChild) {
this.rightChild = rightChild;
}
public void property3(BinaryTree bitree) {
if (bitree == null) {
return;
}
if (bitree.leftChild != null && ((Comparable) bitree.leftChild.data).compareTo(bitree.data) > 0) {
throw new IllegalArgumentException("Binary tree does not satisfy property 3.");
}
if (bitree.rightChild != null && ((Comparable) bitree.rightChild.data).compareTo(bitree.data) < 0) {
throw new IllegalArgumentException("Binary tree does not satisfy property 3.");
}
property3(bitree.leftChild);
property3(bitree.rightChild);
}
public void swap(BinaryTree bitree) {
if (bitree == null) {
return;
}
BinaryTree temp = bitree.leftChild;
bitree.leftChild = bitree.rightChild;
bitree.rightChild = temp;
swap(bitree.leftChild);
swap(bitree.rightChild);
}
public static void main(String[] args) {
BinaryTree root = new BinaryTree<>(4);
BinaryTree node1 = new BinaryTree<>(2);
BinaryTree node2 = new BinaryTree<>(6);
BinaryTree node3 = new BinaryTree<>(1);
BinaryTree node4 = new BinaryTree<>(3);
BinaryTree node5 = new BinaryTree<>(5);
BinaryTree node6 = new BinaryTree<>(7);
root.setLeftChild(node1);
root.setRightChild(node2);
node1.setLeftChild(node3);
node1.setRightChild(node4);
node2.setLeftChild(node5);
node2.setRightChild(node6);
// Test property3 method
try {
root.property3(root);
System.out.println("Binary tree satisfies property 3.");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
// Test swap method
root.swap(root);
System.out.println("In-order traversal after swapping:");
inOrderTraversal(root);
}
private static void inOrderTraversal(BinaryTree bitree) {
if (bitree == null) {
return;
}
inOrderTraversal(bitree.leftChild);
System.out.print(bitree.data + " ");
inOrderTraversal(bitree.rightChild);
}
}
① 验证二叉树的性质3,即对于二叉树中的任意一个结点,其左子树中所有结点的值都小于该结点的值,其右子树中所有结点的值都大于该结点的值。可以通过一次中序遍历来实现,时间复杂度为 O(n),其中 n 为二叉树中结点的个数。
② 交换结点的左右子树,可以通过递归遍历实现,由于每个结点只会被访问一次,因此时间复杂度为 O(n),其中 n 为二叉树中结点的个数。无论是前序遍历、中序遍历还是后序遍历,都可以实现交换结点的左右子树。