【数据结构】树

二叉排序树的实现

二叉排序树:左子节点小于父节点,右子节点大于父节点。

每一个节点在内存当中都是一个对象,通过类构建节点。(类是构建对象的模板)

手动构建: 

public class Test {
	public static void main(String[] args) {
		TreeNode node1 = new TreeNode(5);
		TreeNode node2 = new TreeNode(7);
		TreeNode node3 = new TreeNode(4);
		TreeNode node4 = new TreeNode(2);
		TreeNode node5 = new TreeNode(0);
		TreeNode node6 = new TreeNode(3);
		
		node1.setRightTreeNode(node2);
		node1.setLeftTreeNode(node3);
		node3.setLeftTreeNode(node4);
		node4.setLeftTreeNode(node5);
		node3.setRightTreeNode(node6);
		System.out.println(node1.toString());
	}
}
public class TreeNode {
	private int value;
	private TreeNode leftTreeNode;
	private TreeNode rightTreeNode;
	
	public TreeNode(int data) {
		this.value = data;
	}
	
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public TreeNode getLeftTreeNode() {
		return leftTreeNode;
	}
	public void setLeftTreeNode(TreeNode leftTreeNode) {
		this.leftTreeNode = leftTreeNode;
	}
	public TreeNode getRightTreeNode() {
		return rightTreeNode;
	}
	public void setRightTreeNode(TreeNode rightTreeNode) {
		this.rightTreeNode = rightTreeNode;
	}
	
	@Override
	public String toString() {
		return "TreeNode [value=" + value + ", leftTreeNode=" + leftTreeNode + ", rightTreeNode=" + rightTreeNode + "]";
	}
}

自动构建:

public class Test {
	public static void main(String[] args) {
		BinaryTree binaryTree = new BinaryTree();
		binaryTree.insert(5);
		binaryTree.insert(7);
		binaryTree.insert(4);
		binaryTree.insert(2);
		binaryTree.insert(0);
		binaryTree.insert(3);
		System.out.println(binaryTree.root);
	}
}
public class BinaryTree {
	//定义一个头指针
	public TreeNode root;
	
	public void insert(int value) {
		//新建节点
		TreeNode newNode = new TreeNode(value);
		if (root == null) {
			root = newNode;
			return;
		}
		//定义一个指针来遍历整个树
		TreeNode currentNode = root;
		//定义一个指针指向currentNode的前一个节点,目的是为了方便插入
		TreeNode preNode;
		
		while (true) {
			preNode = currentNode;
			if (newNode.getValue() > currentNode.getValue()) {  //向右走
				currentNode = currentNode.getRightTreeNode();
				if (currentNode == null) {
					preNode.setRightTreeNode(newNode);
					return;
				}
			} else {  //向左走
				currentNode = currentNode.getLeftTreeNode();
				if (currentNode == null) {
					preNode.setLeftTreeNode(newNode);
					return;
				}
			}
		}
	}
}
public class TreeNode {
	private int value;
	private TreeNode leftTreeNode;
	private TreeNode rightTreeNode;
	
	public TreeNode(int data) {
		this.value = data;
	}
	
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	public TreeNode getLeftTreeNode() {
		return leftTreeNode;
	}
	public void setLeftTreeNode(TreeNode leftTreeNode) {
		this.leftTreeNode = leftTreeNode;
	}
	public TreeNode getRightTreeNode() {
		return rightTreeNode;
	}
	public void setRightTreeNode(TreeNode rightTreeNode) {
		this.rightTreeNode = rightTreeNode;
	}
	
	@Override
	public String toString() {
		return "TreeNode [value=" + value + ", leftTreeNode=" + leftTreeNode + ", rightTreeNode=" + rightTreeNode + "]";
	}
}
查询
深度优先遍历

中序遍历:023457

public void inOrder(TreeNode root) {
	if (root == null) {
		return;
	}
	inOrder(root.getLeftTreeNode());
	System.out.println(root.getValue());
	inOrder(root.getRightTreeNode());
}

先序遍历:542037

public void beforeOrder(TreeNode root) {
	if (root == null) {
			return;
	}
	System.out.println(root.getValue());
	beforeOrder(root.getLeftTreeNode());
	beforeOrder(root.getRightTreeNode());
}

后序遍历:032475

public void afterOrder(TreeNode root) {
	if (root == null) {
			return;
	}
	afterOrder(root.getLeftTreeNode());
	afterOrder(root.getRightTreeNode());
	System.out.println(root.getValue());
}
广度优先遍历

队列:先进先出

public void levelOrder() {
	//首先新建一个队列
	LinkedList<TreeNode> queue = new LinkedList<>();
	queue.add(root);  //将根节点放入
	while(!queue.isEmpty()) {
		//头节点出队列
		root = queue.pop();
		if(root.getLeftTreeNode() != null) {
			queue.add(root.getLeftTreeNode());
		}
		if(root.getRightTreeNode() != null) {
			queue.add(root.getRightTreeNode());
		}
	}
}
删除
删除叶子节点

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 确定要删除的target节点和parent节点的关系,是左子树还是右子树。

④ 根据第三步的情况进行删除。

删除只有一个节点的子树

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 确定要删除的target节点和parent节点的关系,是左子树还是右子树。

④ 确定target有的是左子树还是右子树。

⑤ 如果target有左子树

        target是parent的左子树:parent.left = target.left

        target是parent的右子树:parent.right = target.left

⑥ 如果target有右子树

        target是parent的左子树:parent.left = target.right

        target是parent的右子树:parent.right = target.right

删除有两个节点的子树

① 找到要删除的节点target。

② 找到target的父节点parent(要考虑父节点是否存在)。

③ 找到target右子树的最小值(或左子树的最大值)

④ 将右子树的最小值(或左子树的最大值)和target交换,然后删除右子树的最小值(或左子树的最大值)节点。

//找到要删除的节点
	public TreeNode search(TreeNode root, int value) {
		if (root == null) {
			return null;
		}
		if (value == root.getValue()) {
			return root;
		}else if(value < root.getValue()) {
			//判断左子树是否为空
			if (root.getLeftTreeNode() == null) {
				return null;
			}
			return search(root.getLeftTreeNode(), value);
		}else {
			//判断右子树是否为空
			if (root.getRightTreeNode() == null) {
				return null;
			}
			return search(root.getRightTreeNode(), value);
		}
	}
	//找到待删除的父节点
	public TreeNode searchParent(TreeNode root, int value) {
		if (root == null) {
			return null;
		}
		if ((root.getLeftTreeNode() != null && root.getLeftTreeNode().getValue() == value) || 
				(root.getRightTreeNode() != null) && root.getRightTreeNode().getValue() == value)) {
			return root;
		}else {
			if (root.getLeftTreeNode() != null && value < root.getValue()) {
				return searchParent(root.getLeftTreeNode(), value);
			}else if (root.getRightTreeNode() != null && value >= root.getValue()) {
				return search(root.getRightTreeNode(), value);
			}else {
				return null;
			}
		}
	}
	//找到右子树的最小值
	public int rightTreeNodeMin(TreeNode node) {
		TreeNode currentNode = node;
		while (currentNode.getLeftTreeNode() != null) {
			currentNode = currentNode.getLeftTreeNode();
		}
		return currentNode.getValue();
	}
  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的数据结构可以通过使用类和对象来实现。在Python中,我们可以使用节点类来表示的节点,并使用类来操作和管理的结构。 首先,我们可以创建一个节点类,其中包含节点的值和左右子节点的引用。节点的值可以是任意类型的数据。然后,我们可以创建一个类,其中包含根节点的引用和一些方法来操作。 下面是一个示例的Python代码来实现数据结构: ``` class TreeNode: def __init__(self, value): self.value = value self.left = None self.right = None class Tree: def __init__(self): self.root = None def insert(self, value): if self.root is None: self.root = TreeNode(value) else: self._insert_recursive(self.root, value) def _insert_recursive(self, node, value): if value < node.value: if node.left is None: node.left = TreeNode(value) else: self._insert_recursive(node.left, value) else: if node.right is None: node.right = TreeNode(value) else: self._insert_recursive(node.right, value) def search(self, value): return self._search_recursive(self.root, value) def _search_recursive(self, node, value): if node is None or node.value == value: return node if value < node.value: return self._search_recursive(node.left, value) else: return self._search_recursive(node.right, value) def inorder_traversal(self): nodes = [] self._inorder_traversal_recursive(self.root, nodes) return nodes def _inorder_traversal_recursive(self, node, nodes): if node is not None: self._inorder_traversal_recursive(node.left, nodes) nodes.append(node.value) self._inorder_traversal_recursive(node.right, nodes) ``` 在上面的代码中,我们创建了一个`TreeNode`类来表示的节点,每个节点有一个值和左右子节点的引用。然后,我们创建了一个`Tree`类来操作和管理的结构。`Tree`类包括了插入节点、搜索节点和中序遍历的方法。 使用这些类,我们可以轻松地创建一个二叉搜索,并对其进行插入、搜索和中序遍历等操作。 例如,我们可以创建一个对象并插入一些节点: ``` tree = Tree() tree.insert(5) tree.insert(3) tree.insert(7) tree.insert(2) tree.insert(4) ``` 然后,我们可以搜索特定的值: ``` node = tree.search(3) if node is not None: print("Found:", node.value) else: print("Not found") ``` 最后,我们可以使用中序遍历方法打印的节点值: ``` nodes = tree.inorder_traversal() print("Inorder traversal:", nodes) ``` 这是一个简单的例子来演示如何在Python中实现数据结构。通过使用节点类和类,我们可以方便地创建和操作的结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值