基于SystemVerilog OOP特性实现可增删遍历的n节点二叉树咨询
用SystemVerilog OOP实现可操作的二叉树
当然可以用SystemVerilog的面向对象特性实现支持动态节点操作的二叉树。下面基于你提供的初始代码,扩展实现添加节点、删除指定节点和三种遍历打印的完整功能:
完整实现代码
class node; int val; node left, right; function new(int data); val = data; left = null; right = null; endfunction endclass class btree; node root; function new(int info); root = new(info); endfunction // 插入节点(递归实现) function void insert(int data); root = insert_recursive(root, data); endfunction function node insert_recursive(node current, int data); if (current == null) begin return new node(data); end if (data < current.val) begin current.left = insert_recursive(current.left, data); end else if (data > current.val) begin current.right = insert_recursive(current.right, data); end // 忽略重复值,需支持可自行添加逻辑 return current; endfunction // 删除节点(递归实现) function void delete(int data); root = delete_recursive(root, data); endfunction function node delete_recursive(node current, int data); if (current == null) begin return current; end // 定位目标节点 if (data < current.val) begin current.left = delete_recursive(current.left, data); end else if (data > current.val) begin current.right = delete_recursive(current.right, data); end else begin // 情况1:叶子节点/仅单个子节点 if (current.left == null) begin return current.right; end else if (current.right == null) begin return current.left; end // 情况2:两个子节点,取右子树最小值替代当前节点 current.val = find_min(current.right); current.right = delete_recursive(current.right, current.val); end return current; endfunction // 查找子树最小值(辅助删除逻辑) function int find_min(node current); while (current.left != null) begin current = current.left; end return current.val; endfunction // 前序遍历打印 function void preorder(); $write("前序遍历:"); preorder_recursive(root); $write("\n"); endfunction function void preorder_recursive(node current); if (current != null) begin $write("%0d ", current.val); preorder_recursive(current.left); preorder_recursive(current.right); end endfunction // 中序遍历打印 function void inorder(); $write("中序遍历:"); inorder_recursive(root); $write("\n"); endfunction function void inorder_recursive(node current); if (current != null) begin inorder_recursive(current.left); $write("%0d ", current.val); inorder_recursive(current.right); end endfunction // 后序遍历打印 function void postorder(); $write("后序遍历:"); postorder_recursive(root); $write("\n"); endfunction function void postorder_recursive(node current); if (current != null) begin postorder_recursive(current.left); postorder_recursive(current.right); $write("%0d ", current.val); end endfunction endclass module abc(); btree b1; initial begin // 初始化二叉树,根节点值为5 b1 = new(5); // 批量插入节点 b1.insert(3); b1.insert(7); b1.insert(2); b1.insert(4); b1.insert(6); b1.insert(8); // 打印三种遍历结果 b1.preorder(); b1.inorder(); b1.postorder(); // 删除节点示例:删除值为3的节点 $write("\n删除节点3后:\n"); b1.delete(3); b1.inorder(); // 删除根节点示例:删除值为5的节点 $write("\n删除根节点5后:\n"); b1.delete(5); b1.inorder(); end endmodule
功能细节说明
插入节点
- 用递归逻辑从根节点开始比对:
- 待插入值小于当前节点,递归处理左子树;大于则处理右子树
- 碰到空节点时创建新的
node对象并返回,完成插入
- 当前实现忽略重复值,若需要支持重复节点,可自行添加逻辑(比如将重复值挂载到左/右子树)
删除节点
针对三种节点情况做处理:
- 叶子节点:直接返回
null,相当于移除该节点 - 仅单个子节点:用子节点替代当前节点位置
- 两个子节点:取右子树的最小节点值替换当前节点,再递归删除那个最小节点,保证树的结构完整性
遍历打印
实现三种经典二叉树遍历:
- 前序遍历:根节点 → 左子树 → 右子树
- 中序遍历:左子树 → 根节点 → 右子树(二叉搜索树的中序遍历结果为有序序列)
- 后序遍历:左子树 → 右子树 → 根节点
示例运行输出
前序遍历:5 3 2 4 7 6 8 中序遍历:2 3 4 5 6 7 8 后序遍历:2 4 3 6 8 7 5 删除节点3后: 中序遍历:2 4 5 6 7 8 删除根节点5后: 中序遍历:2 4 6 7 8
内容的提问来源于stack exchange,提问作者xxxl_eet
相关产品推荐
相关产品推荐

