删除链表中结点可能出现的错误

博客介绍了链表结点删除的要点,删除结点时,应先将其指针域置为null,否则可能导致该结点仍接上链表;若删除末尾结点,需调整前一个结点对应指针域的值。

要删除链表中结点的时候,删除的结点最好要先将其指针域置为null,不然可能删除后也会指向链表中的空间,导致其接上了链表,如果删除的是末尾的结点,那么就需要调整前一个结点的对应指针域的值

<think>我们参考引用[2]和引用[4]中关于二叉树节点删除的方法,特别是引用[2]详细描述了删除节点的三种情况,引用[4]提供了递归实现的代码。 删除节点需要考虑三种情况: 1. 被删除节点是叶子节点(无子节点):直接删除。 2. 被删除节点只有一个子节点:用其子节点替代。 3. 被删除节点有两个子节点:找到右子树的最小节点(或左子树的最大节点)的值复制到当前节点,然后删除那个最小(或最大)节点(此时该节点最多只有一个子节点,可转化为前两种情况)。 我们将实现一个非递归版本和一个递归版本的删除操作。假设我们的二叉树节点结构如下(参考引用[3]): ```cpp struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode() : val(0), left(nullptr), right(nullptr) {} TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} }; ``` 我们以二叉搜索树(BST)为例,因为二叉搜索树有明确的节点值大小关系,删除时需要保持BST的性质。 非递归删除方法步骤: 1. 首先找到要删除的节点及其父节点(因为需要修改父节点的指针)。 2. 根据节点的子节点情况处理: a. 无子节点:父节点指向该节点的指针置为nullptr。 b. 只有一个子节点:父节点指向该节点的指针指向该节点的子节点。 c. 有两个子节点:找到右子树的最小节点(或左子树的最大节点),记录其值,然后递归删除该最小节点,并将当前节点的值替换为最小节点的值。 递归删除方法(参考引用[4]): 使用递归可以避免显式记录父节点,通过引用传递节点指针。 我们分别实现这两种方法。 注意:在非递归方法中,如果要删除的是根节点,需要特殊处理(或者使用指向指针的指针)。 下面我们给出代码实现:</think>### C++二叉树节点删除实现详解 在二叉树中删除节点需要处理三种情况,确保删除后仍保持树结构的完整性[^2]。以下是基于二叉搜索树(BST)的节点删除实现方法: #### 节点结构定义 ```cpp struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} }; ``` #### 删除操作实现 ```cpp TreeNode* deleteNode(TreeNode* root, int key) { if (!root) return nullptr; // 空树处理 // 1. 查找目标节点 if (key < root->val) { root->left = deleteNode(root->left, key); } else if (key > root->val) { root->right = deleteNode(root->right, key); } else { // 2. 找到目标节点后的删除逻辑 // 情况1: 无子节点或单子节点 if (!root->left) { TreeNode* temp = root->right; delete root; return temp; } else if (!root->right) { TreeNode* temp = root->left; delete root; return temp; } // 情况2: 双子节点(替换法) TreeNode* successor = root->right; while (successor->left) { successor = successor->left; // 找右子树最小节点 } root->val = successor->val; // 值替换 root->right = deleteNode(root->right, successor->val); // 删除后继节点 } return root; } ``` #### 关键处理逻辑 1. **叶子节点**:直接删除,父节点指针置空 ```cpp // 示例:删除节点5 parent->left = nullptr; // 或 parent->right delete node; ``` 2. **单子节点**:子节点替代被删节点位置 ```cpp // 示例:删除只有左子树的节点 parent->left = node->left; // 孙子变儿子 delete node; ``` 3. **双子节点**(核心难点): - 找到右子树最小节点(或左子树最大节点) - 复制其值到被删节点 - 递归删除该后继节点 ```cpp // 替换值后删除后继节点 node->val = successor->val; node->right = deleteNode(node->right, successor->val); ``` #### 时间复杂度分析 - 平均情况:$O(\log n)$(平衡二叉树) - 最坏情况:$O(n)$(退化成链表) #### 注意事项 1. 内存管理:删除后及时释放节点内存 2. 平衡性:频繁删除可能破坏BST平衡性,可考虑AVL/红黑树 3. 特殊处理:根节点删除需要更新树根指针 > 示例:删除节点6(双子节点情况) > 1. 找到右子树最小节点7 > 2. 将6的值替换为7 > 3. 在右子树中递归删除原节点7 > > 最终树结构保持二叉搜索树性质[^2][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值