数据结构实验(二叉树的操作)

  • 实验内容

实验一:BinaryTree二叉树类增加以下成员方法,public 权限

    • BinaryTree create(SeqList inList, SeqList postList);  //以中根和后根遍历序列构造二叉树
    • void leaf();   //输出叶子结点
    • BinaryNode parent(BinaryNode p);    //返回p结点的父母结点

实验二:实现以下对二叉树的操作,public static 修饰,要求一次遍历效率

    • void property3(BinaryTree bitree);     //验证二叉树的性质3
    • void swap(BinaryTree bitree);   //交换结点的左右子树,讨论3种遍历算法的可行性
  • 实验方法及实现

根据实验内容和要求,将自己实现的程序代码写在此处,分析算法的时间复杂度。

实验一: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 inList, SeqList postList) 方法的时间复杂度为 O(n^2),其中 n 为二叉树的结点数。

leaf() 方法的时间复杂度为 O(n),其中 n 为二叉树的结点数。

parent(BinaryNode p) 方法的时间复杂度为 O(n),其中 n 为二叉树的结点数。

实验二:

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 为二叉树中结点的个数。无论是前序遍历、中序遍历还是后序遍历,都可以实现交换结点的左右子树。

你可能感兴趣的:(算法,java,数据结构)