📜  线程二进制搜索树|删除中

📅  最后修改于: 2021-05-24 21:37:26             🧑  作者: Mango

线程二叉树节点如下所示。

CPP
struct Node {
    struct Node *left, *right;
    int info;
 
    // True if left pointer points to predecessor
    // in Inorder Traversal
    bool lthread;
 
    // True if right pointer points to predecessor
    // in Inorder Traversal
    bool rthread;
};


Java
static class Node {
    Node left, right;
    int info;
 
    // True if left pointer points to predecessor
    // in Inorder Traversal
    boolean lthread;
 
    // True if right pointer points to predecessor
    // in Inorder Traversal
    boolean rthread;
};
 
 
// This code contributed by aashish1995


C#
public
  class Node
  {
    public
      Node left,
    right;
    public
      int info;
 
    // True if left pointer points to predecessor
    // in Inorder Traversal
    public
      bool lthread;
 
    // True if right pointer points to predecessor
    // in Inorder Traversal
    public
      bool rthread;
  };
 
// This code is contributed by aashish1995


CPP
// Deletes a key from threaded BST with given root and
// returns new root of BST.
struct Node* delThreadedBST(struct Node* root, int dkey)
{
    // Initialize parent as NULL and ptrent
    // Node as root.
    struct Node *par = NULL, *ptr = root;
 
    // Set true if key is found
    int found = 0;
 
    // Search key in BST : find Node and its
    // parent.
    while (ptr != NULL) {
        if (dkey == ptr->info) {
            found = 1;
            break;
        }
        par = ptr;
        if (dkey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    if (found == 0)
        printf("dkey not present in tree\n");
 
    // Two Children
    else if (ptr->lthread == false && ptr->rthread == false)
        root = caseC(root, par, ptr);
 
    // Only Left Child
    else if (ptr->lthread == false)
        root = caseB(root, par, ptr);
 
    // Only Right Child
    else if (ptr->rthread == false)
        root = caseB(root, par, ptr);
 
    // No child
    else
        root = caseA(root, par, ptr);
 
    return root;
}


CPP
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseA(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // If Node to be deleted is root
    if (par == NULL)
        root = NULL;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par->left) {
        par->lthread = true;
        par->left = ptr->left;
    }
    else {
        par->rthread = true;
        par->right = ptr->right;
    }
 
    // Free memory and return new root
    free(ptr);
    return root;
}


Java
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
Node caseA(Node root, Node par,
                   Node ptr)
{
   
    // If Node to be deleted is root
    if (par == null)
        root = null;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par.left) {
        par.lthread = true;
        par.left = ptr.left;
    }
    else {
        par.rthread = true;
        par.right = ptr.right;
    }
 
    return root;
}
 
// This code is contributed by gauravrajput1


CPP
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseB(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    struct Node* child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr->lthread == false)
        child = ptr->left;
 
    // Node to be deleted has right child.
    else
        child = ptr->right;
 
    // Node to be deleted is root Node.
    if (par == NULL)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par->left)
        par->left = child;
    else
        par->right = child;
 
    // Find successor and predecessor
    Node* s = inSucc(ptr);
    Node* p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr->lthread == false)
        p->right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr->rthread == false)
            s->left = p;
    }
 
    free(ptr);
    return root;
}


Java
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
static Node caseB(Node root, Node par,
                   Node ptr)
{
    Node child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr.lthread == false)
        child = ptr.left;
 
    // Node to be deleted has right child.
    else
        child = ptr.right;
 
    // Node to be deleted is root Node.
    if (par == null)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par.left)
        par.left = child;
    else
        par.right = child;
 
    // Find successor and predecessor
    Node s = inSucc(ptr);
    Node p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr.lthread == false)
        p.right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr.rthread == false)
            s.left = p;
    }
    return root;
}
 
// This code is contributed by gauravrajput1


CPP
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseC(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // Find inorder successor and its parent.
    struct Node* parsucc = ptr;
    struct Node* succ = ptr->right;
 
    // Find leftmost child of successor
    while (succ->left != NULL) {
        parsucc = succ;
        succ = succ->left;
    }
 
    ptr->info = succ->info;
 
    if (succ->lthread == true && succ->rthread == true)
        root = caseA(root, parsucc, succ);
    else
        root = caseB(root, parsucc, succ);
 
    return root;
}


C++
// Complete C++ program to demonstrate deletion
// in threaded BST
#include 
using namespace std;
 
struct Node {
    struct Node *left, *right;
    int info;
 
    // True if left pointer points to predecessor
    // in Inorder Traversal
    bool lthread;
 
    // True if right pointer points to predecessor
    // in Inorder Traversal
    bool rthread;
};
 
// Insert a Node in Binary Threaded Tree
struct Node* insert(struct Node* root, int ikey)
{
    // Searching for a Node with given value
    Node* ptr = root;
    Node* par = NULL; // Parent of key to be inserted
    while (ptr != NULL) {
        // If key already exists, return
        if (ikey == (ptr->info)) {
            printf("Duplicate Key !\n");
            return root;
        }
 
        par = ptr; // Update parent pointer
 
        // Moving on left subtree.
        if (ikey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
 
        // Moving on right subtree.
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    // Create a new Node
    Node* tmp = new Node;
    tmp->info = ikey;
    tmp->lthread = true;
    tmp->rthread = true;
 
    if (par == NULL) {
        root = tmp;
        tmp->left = NULL;
        tmp->right = NULL;
    }
    else if (ikey < (par->info)) {
        tmp->left = par->left;
        tmp->right = par;
        par->lthread = false;
        par->left = tmp;
    }
    else {
        tmp->left = par;
        tmp->right = par->right;
        par->rthread = false;
        par->right = tmp;
    }
 
    return root;
}
 
// Returns inorder successor using left
// and right children (Used in deletion)
struct Node* inSucc(struct Node* ptr)
{
    if (ptr->rthread == true)
        return ptr->right;
 
    ptr = ptr->right;
    while (ptr->lthread == false)
        ptr = ptr->left;
 
    return ptr;
}
 
// Returns inorder successor using rthread
// (Used in inorder)
struct Node* inorderSuccessor(struct Node* ptr)
{
    // If rthread is set, we can quickly find
    if (ptr->rthread == true)
        return ptr->right;
 
    // Else return leftmost child of right subtree
    ptr = ptr->right;
    while (ptr->lthread == false)
        ptr = ptr->left;
    return ptr;
}
 
// Printing the threaded tree
void inorder(struct Node* root)
{
    if (root == NULL)
        printf("Tree is empty");
 
    // Reach leftmost Node
    struct Node* ptr = root;
    while (ptr->lthread == false)
        ptr = ptr->left;
 
    // One by one print successors
    while (ptr != NULL) {
        printf("%d ", ptr->info);
        ptr = inorderSuccessor(ptr);
    }
}
 
struct Node* inPred(struct Node* ptr)
{
    if (ptr->lthread == true)
        return ptr->left;
 
    ptr = ptr->left;
    while (ptr->rthread == false)
        ptr = ptr->right;
    return ptr;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseA(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // If Node to be deleted is root
    if (par == NULL)
        root = NULL;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par->left) {
        par->lthread = true;
        par->left = ptr->left;
    }
    else {
        par->rthread = true;
        par->right = ptr->right;
    }
 
    // Free memory and return new root
    free(ptr);
    return root;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseB(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    struct Node* child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr->lthread == false)
        child = ptr->left;
 
    // Node to be deleted has right child.
    else
        child = ptr->right;
 
    // Node to be deleted is root Node.
    if (par == NULL)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par->left)
        par->left = child;
    else
        par->right = child;
 
    // Find successor and predecessor
    Node* s = inSucc(ptr);
    Node* p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr->lthread == false)
        p->right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr->rthread == false)
            s->left = p;
    }
 
    free(ptr);
    return root;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseC(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // Find inorder successor and its parent.
    struct Node* parsucc = ptr;
    struct Node* succ = ptr->right;
 
    // Find leftmost child of successor
    while (succ->lthread==false) {
        parsucc = succ;
        succ = succ->left;
    }
 
    ptr->info = succ->info;
 
    if (succ->lthread == true && succ->rthread == true)
        root = caseA(root, parsucc, succ);
    else
        root = caseB(root, parsucc, succ);
 
    return root;
}
 
// Deletes a key from threaded BST with given root and
// returns new root of BST.
struct Node* delThreadedBST(struct Node* root, int dkey)
{
    // Initialize parent as NULL and ptrent
    // Node as root.
    struct Node *par = NULL, *ptr = root;
 
    // Set true if key is found
    int found = 0;
 
    // Search key in BST : find Node and its
    // parent.
    while (ptr != NULL) {
        if (dkey == ptr->info) {
            found = 1;
            break;
        }
        par = ptr;
        if (dkey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    if (found == 0)
        printf("dkey not present in tree\n");
 
    // Two Children
    else if (ptr->lthread == false && ptr->rthread == false)
        root = caseC(root, par, ptr);
 
    // Only Left Child
    else if (ptr->lthread == false)
        root = caseB(root, par, ptr);
 
    // Only Right Child
    else if (ptr->rthread == false)
        root = caseB(root, par, ptr);
 
    // No child
    else
        root = caseA(root, par, ptr);
 
    return root;
}
 
// Driver Program
int main()
{
    struct Node* root = NULL;
 
    root = insert(root, 20);
    root = insert(root, 10);
    root = insert(root, 30);
    root = insert(root, 5);
    root = insert(root, 16);
    root = insert(root, 14);
    root = insert(root, 17);
    root = insert(root, 13);
 
    root = delThreadedBST(root, 20);
    inorder(root);
 
    return 0;
}


Java
// Complete Java program to demonstrate deletion
// in threaded BST
import java.util.*;
class solution {
 
    static class Node {
        Node left, right;
        int info;
 
        // True if left pointer points to predecessor
        // in Inorder Traversal
        boolean lthread;
 
        // True if right pointer points to predecessor
        // in Inorder Traversal
        boolean rthread;
    };
 
    // Insert a Node in Binary Threaded Tree
    static Node insert(Node root, int ikey)
    {
        // Searching for a Node with given value
        Node ptr = root;
        Node par = null; // Parent of key to be inserted
        while (ptr != null) {
            // If key already exists, return
            if (ikey == (ptr.info)) {
                System.out.printf("Duplicate Key !\n");
                return root;
            }
 
            par = ptr; // Update parent pointer
 
            // Moving on left subtree.
            if (ikey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
 
            // Moving on right subtree.
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        // Create a new Node
        Node tmp = new Node();
        tmp.info = ikey;
        tmp.lthread = true;
        tmp.rthread = true;
 
        if (par == null) {
            root = tmp;
            tmp.left = null;
            tmp.right = null;
        }
        else if (ikey < (par.info)) {
            tmp.left = par.left;
            tmp.right = par;
            par.lthread = false;
            par.left = tmp;
        }
        else {
            tmp.left = par;
            tmp.right = par.right;
            par.rthread = false;
            par.right = tmp;
        }
 
        return root;
    }
 
    // Returns inorder successor using left
    // and right children (Used in deletion)
    static Node inSucc(Node ptr)
    {
        if (ptr.rthread == true)
            return ptr.right;
 
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        return ptr;
    }
 
    // Returns inorder successor using rthread
    // (Used in inorder)
    static Node inorderSuccessor(Node ptr)
    {
        // If rthread is set, we can quickly find
        if (ptr.rthread == true)
            return ptr.right;
 
        // Else return leftmost child of right subtree
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
        return ptr;
    }
 
    // Printing the threaded tree
    static void inorder(Node root)
    {
        if (root == null)
            System.out.printf("Tree is empty");
 
        // Reach leftmost Node
        Node ptr = root;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        // One by one print successors
        while (ptr != null) {
            System.out.printf("%d ", ptr.info);
            ptr = inorderSuccessor(ptr);
        }
    }
 
    static Node inPred(Node ptr)
    {
        if (ptr.lthread == true)
            return ptr.left;
 
        ptr = ptr.left;
        while (ptr.rthread == false)
            ptr = ptr.right;
        return ptr;
      
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseA(Node root, Node par,
                      Node ptr)
    {
        // If Node to be deleted is root
        if (par == null)
            root = null;
 
        // If Node to be deleted is left
        // of its parent
        else if (ptr == par.left) {
            par.lthread = true;
            par.left = ptr.left;
        }
        else {
            par.rthread = true;
            par.right = ptr.right;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseB(Node root, Node par,
                      Node ptr)
    {
        Node child;
 
        // Initialize child Node to be deleted has
        // left child.
        if (ptr.lthread == false)
            child = ptr.left;
 
        // Node to be deleted has right child.
        else
            child = ptr.right;
 
        // Node to be deleted is root Node.
        if (par == null)
            root = child;
 
        // Node is left child of its parent.
        else if (ptr == par.left)
            par.left = child;
        else
            par.right = child;
 
        // Find successor and predecessor
        Node s = inSucc(ptr);
        Node p = inPred(ptr);
 
        // If ptr has left subtree.
        if (ptr.lthread == false)
            p.right = s;
 
        // If ptr has right subtree.
        else {
            if (ptr.rthread == false)
                s.left = p;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseC(Node root, Node par,
                      Node ptr)
    {
        // Find inorder successor and its parent.
        Node parsucc = ptr;
        Node succ = ptr.right;
 
        // Find leftmost child of successor
        while (succ.lthread == false) {
            parsucc = succ;
            succ = succ.left;
        }
 
        ptr.info = succ.info;
 
        if (succ.lthread == true && succ.rthread == true)
            root = caseA(root, parsucc, succ);
        else
            root = caseB(root, parsucc, succ);
 
        return root;
    }
 
    // Deletes a key from threaded BST with given root and
    // returns new root of BST.
    static Node delThreadedBST(Node root, int dkey)
    {
        // Initialize parent as null and ptrent
        // Node as root.
        Node par = null, ptr = root;
 
        // Set true if key is found
        int found = 0;
 
        // Search key in BST : find Node and its
        // parent.
        while (ptr != null) {
            if (dkey == ptr.info) {
                found = 1;
                break;
            }
            par = ptr;
            if (dkey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        if (found == 0)
            System.out.printf("dkey not present in tree\n");
 
        // Two Children
        else if (ptr.lthread == false && ptr.rthread == false)
            root = caseC(root, par, ptr);
 
        // Only Left Child
        else if (ptr.lthread == false)
            root = caseB(root, par, ptr);
 
        // Only Right Child
        else if (ptr.rthread == false)
            root = caseB(root, par, ptr);
 
        // No child
        else
            root = caseA(root, par, ptr);
 
        return root;
    }
 
    // Driver Program
    public static void main(String args[])
    {
        Node root = null;
 
        root = insert(root, 20);
        root = insert(root, 10);
        root = insert(root, 30);
        root = insert(root, 5);
        root = insert(root, 16);
        root = insert(root, 14);
        root = insert(root, 17);
        root = insert(root, 13);
 
        root = delThreadedBST(root, 20);
        inorder(root);
    }
}
// This code is contributed by Arnab Kundu


C#
// Complete C# program to demonstrate deletion
// in threaded BST
using System;
 
class GFG {
 
    public class Node {
        public Node left, right;
        public int info;
 
        // True if left pointer points to predecessor
        // in Inorder Traversal
        public bool lthread;
 
        // True if right pointer points to predecessor
        // in Inorder Traversal
        public bool rthread;
    };
 
    // Insert a Node in Binary Threaded Tree
    static Node insert(Node root, int ikey)
    {
        // Searching for a Node with given value
        Node ptr = root;
        Node par = null; // Parent of key to be inserted
        while (ptr != null) {
            // If key already exists, return
            if (ikey == (ptr.info)) {
                Console.Write("Duplicate Key !\n");
                return root;
            }
 
            par = ptr; // Update parent pointer
 
            // Moving on left subtree.
            if (ikey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
 
            // Moving on right subtree.
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        // Create a new Node
        Node tmp = new Node();
        tmp.info = ikey;
        tmp.lthread = true;
        tmp.rthread = true;
 
        if (par == null) {
            root = tmp;
            tmp.left = null;
            tmp.right = null;
        }
        else if (ikey < (par.info)) {
            tmp.left = par.left;
            tmp.right = par;
            par.lthread = false;
            par.left = tmp;
        }
        else {
            tmp.left = par;
            tmp.right = par.right;
            par.rthread = false;
            par.right = tmp;
        }
 
        return root;
    }
 
    // Returns inorder successor using left
    // and right children (Used in deletion)
    static Node inSucc(Node ptr)
    {
        if (ptr.rthread == true)
            return ptr.right;
 
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        return ptr;
    }
 
    // Returns inorder successor using rthread
    // (Used in inorder)
    static Node inorderSuccessor(Node ptr)
    {
        // If rthread is set, we can quickly find
        if (ptr.rthread == true)
            return ptr.right;
 
        // Else return leftmost child of right subtree
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
        return ptr;
    }
 
    // Printing the threaded tree
    static void inorder(Node root)
    {
        if (root == null)
            Console.Write("Tree is empty");
 
        // Reach leftmost Node
        Node ptr = root;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        // One by one print successors
        while (ptr != null) {
            Console.Write("{0} ", ptr.info);
            ptr = inorderSuccessor(ptr);
        }
    }
 
    static Node inPred(Node ptr)
    {
        if (ptr.lthread == true)
            return ptr.left;
 
        ptr = ptr.left;
        while (ptr.rthread == false)
            ptr = ptr.right;
        return ptr;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseA(Node root, Node par,
                      Node ptr)
    {
        // If Node to be deleted is root
        if (par == null)
            root = null;
 
        // If Node to be deleted is left
        // of its parent
        else if (ptr == par.left) {
            par.lthread = true;
            par.left = ptr.left;
        }
        else {
            par.rthread = true;
            par.right = ptr.right;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseB(Node root, Node par,
                      Node ptr)
    {
        Node child;
 
        // Initialize child Node to be deleted has
        // left child.
        if (ptr.lthread == false)
            child = ptr.left;
 
        // Node to be deleted has right child.
        else
            child = ptr.right;
 
        // Node to be deleted is root Node.
        if (par == null)
            root = child;
 
        // Node is left child of its parent.
        else if (ptr == par.left)
            par.left = child;
        else
            par.right = child;
 
        // Find successor and predecessor
        Node s = inSucc(ptr);
        Node p = inPred(ptr);
 
        // If ptr has left subtree.
        if (ptr.lthread == false)
            p.right = s;
 
        // If ptr has right subtree.
        else {
            if (ptr.rthread == false)
                s.left = p;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseC(Node root, Node par,
                      Node ptr)
    {
        // Find inorder successor and its parent.
        Node parsucc = ptr;
        Node succ = ptr.right;
 
        // Find leftmost child of successor
        while (succ.lthread == false) {
            parsucc = succ;
            succ = succ.left;
        }
 
        ptr.info = succ.info;
 
        if (succ.lthread == true && succ.rthread == true)
            root = caseA(root, parsucc, succ);
        else
            root = caseB(root, parsucc, succ);
 
        return root;
    }
 
    // Deletes a key from threaded BST with given root and
    // returns new root of BST.
    static Node delThreadedBST(Node root, int dkey)
    {
        // Initialize parent as null and ptrent
        // Node as root.
        Node par = null, ptr = root;
 
        // Set true if key is found
        int found = 0;
 
        // Search key in BST : find Node and its
        // parent.
        while (ptr != null) {
            if (dkey == ptr.info) {
                found = 1;
                break;
            }
            par = ptr;
            if (dkey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        if (found == 0)
            Console.Write("dkey not present in tree\n");
 
        // Two Children
        else if (ptr.lthread == false && ptr.rthread == false)
            root = caseC(root, par, ptr);
 
        // Only Left Child
        else if (ptr.lthread == false)
            root = caseB(root, par, ptr);
 
        // Only Right Child
        else if (ptr.rthread == false)
            root = caseB(root, par, ptr);
 
        // No child
        else
            root = caseA(root, par, ptr);
 
        return root;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Node root = null;
 
        root = insert(root, 20);
        root = insert(root, 10);
        root = insert(root, 30);
        root = insert(root, 5);
        root = insert(root, 16);
        root = insert(root, 14);
        root = insert(root, 17);
        root = insert(root, 13);
 
        root = delThreadedBST(root, 20);
        inorder(root);
    }
}
 
// This code has been contributed by 29AjayKumar


我们已经讨论了线程二叉搜索树的插入
在删除中,首先搜索要删除的密钥,然后有不同的情况用于删除在其中找到密钥的节点。

CPP

// Deletes a key from threaded BST with given root and
// returns new root of BST.
struct Node* delThreadedBST(struct Node* root, int dkey)
{
    // Initialize parent as NULL and ptrent
    // Node as root.
    struct Node *par = NULL, *ptr = root;
 
    // Set true if key is found
    int found = 0;
 
    // Search key in BST : find Node and its
    // parent.
    while (ptr != NULL) {
        if (dkey == ptr->info) {
            found = 1;
            break;
        }
        par = ptr;
        if (dkey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    if (found == 0)
        printf("dkey not present in tree\n");
 
    // Two Children
    else if (ptr->lthread == false && ptr->rthread == false)
        root = caseC(root, par, ptr);
 
    // Only Left Child
    else if (ptr->lthread == false)
        root = caseB(root, par, ptr);
 
    // Only Right Child
    else if (ptr->rthread == false)
        root = caseB(root, par, ptr);
 
    // No child
    else
        root = caseA(root, par, ptr);
 
    return root;
}

情况A:需要删除叶节点
在BST中,为了删除叶节点,将父节点的左或右指针设置为NULL。在这里,不是将指针设置为NULL,而是创建了一个线程。
如果要删除的叶节点是其父节点的左子节点,则在删除后,父节点的左指针应成为一个指向删除后其父节点的前身的线程。

par -> lthread = true;
par -> left = ptr -> left;

如果要删除的叶节点是其父节点的右子节点,则在删除后,父节点的右指针应成为指向其后继节点的线程。删除前为叶节点的有序后继节点的节点将成为删除后父节点的有序后继节点。

CPP

// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseA(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // If Node to be deleted is root
    if (par == NULL)
        root = NULL;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par->left) {
        par->lthread = true;
        par->left = ptr->left;
    }
    else {
        par->rthread = true;
        par->right = ptr->right;
    }
 
    // Free memory and return new root
    free(ptr);
    return root;
}

Java

// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
Node caseA(Node root, Node par,
                   Node ptr)
{
   
    // If Node to be deleted is root
    if (par == null)
        root = null;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par.left) {
        par.lthread = true;
        par.left = ptr.left;
    }
    else {
        par.rthread = true;
        par.right = ptr.right;
    }
 
    return root;
}
 
// This code is contributed by gauravrajput1

情况B:要删除的节点只有一个孩子
在像BST中一样删除节点后,将发现节点的有序后继者和有序前任者。

s = inSucc(ptr);
p = inPred(ptr);

如果要删除的节点具有左子树,则在删除后,其前任节点的右线程应指向其后继节点。

p->left = s;

在删除15之前,2是16的后继。在删除16之后,节点20成为15的后继,因此15的右线程将指向20。
如果要删除的节点具有右子树,则在删除后,其后继者的左线程应指向其前任者。

s->left = p;

在删除25之前是34的前继者,在34之前是30的后继者。在删除30之后,节点25成为34的前任,因此34的左线程将指向25。

CPP

// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseB(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    struct Node* child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr->lthread == false)
        child = ptr->left;
 
    // Node to be deleted has right child.
    else
        child = ptr->right;
 
    // Node to be deleted is root Node.
    if (par == NULL)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par->left)
        par->left = child;
    else
        par->right = child;
 
    // Find successor and predecessor
    Node* s = inSucc(ptr);
    Node* p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr->lthread == false)
        p->right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr->rthread == false)
            s->left = p;
    }
 
    free(ptr);
    return root;
}

Java

// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
static Node caseB(Node root, Node par,
                   Node ptr)
{
    Node child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr.lthread == false)
        child = ptr.left;
 
    // Node to be deleted has right child.
    else
        child = ptr.right;
 
    // Node to be deleted is root Node.
    if (par == null)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par.left)
        par.left = child;
    else
        par.right = child;
 
    // Find successor and predecessor
    Node s = inSucc(ptr);
    Node p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr.lthread == false)
        p.right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr.rthread == false)
            s.left = p;
    }
    return root;
}
 
// This code is contributed by gauravrajput1

情况C:要删除的节点有两个子节点
我们找到Node ptr的有序后继者(要删除的Node),然后将该后继者的信息复制到Node ptr中。在此有序后继节点之后,使用案例A或案例B删除。

CPP

// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseC(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // Find inorder successor and its parent.
    struct Node* parsucc = ptr;
    struct Node* succ = ptr->right;
 
    // Find leftmost child of successor
    while (succ->left != NULL) {
        parsucc = succ;
        succ = succ->left;
    }
 
    ptr->info = succ->info;
 
    if (succ->lthread == true && succ->rthread == true)
        root = caseA(root, parsucc, succ);
    else
        root = caseB(root, parsucc, succ);
 
    return root;
}

以下是完整的代码:

C++

// Complete C++ program to demonstrate deletion
// in threaded BST
#include 
using namespace std;
 
struct Node {
    struct Node *left, *right;
    int info;
 
    // True if left pointer points to predecessor
    // in Inorder Traversal
    bool lthread;
 
    // True if right pointer points to predecessor
    // in Inorder Traversal
    bool rthread;
};
 
// Insert a Node in Binary Threaded Tree
struct Node* insert(struct Node* root, int ikey)
{
    // Searching for a Node with given value
    Node* ptr = root;
    Node* par = NULL; // Parent of key to be inserted
    while (ptr != NULL) {
        // If key already exists, return
        if (ikey == (ptr->info)) {
            printf("Duplicate Key !\n");
            return root;
        }
 
        par = ptr; // Update parent pointer
 
        // Moving on left subtree.
        if (ikey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
 
        // Moving on right subtree.
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    // Create a new Node
    Node* tmp = new Node;
    tmp->info = ikey;
    tmp->lthread = true;
    tmp->rthread = true;
 
    if (par == NULL) {
        root = tmp;
        tmp->left = NULL;
        tmp->right = NULL;
    }
    else if (ikey < (par->info)) {
        tmp->left = par->left;
        tmp->right = par;
        par->lthread = false;
        par->left = tmp;
    }
    else {
        tmp->left = par;
        tmp->right = par->right;
        par->rthread = false;
        par->right = tmp;
    }
 
    return root;
}
 
// Returns inorder successor using left
// and right children (Used in deletion)
struct Node* inSucc(struct Node* ptr)
{
    if (ptr->rthread == true)
        return ptr->right;
 
    ptr = ptr->right;
    while (ptr->lthread == false)
        ptr = ptr->left;
 
    return ptr;
}
 
// Returns inorder successor using rthread
// (Used in inorder)
struct Node* inorderSuccessor(struct Node* ptr)
{
    // If rthread is set, we can quickly find
    if (ptr->rthread == true)
        return ptr->right;
 
    // Else return leftmost child of right subtree
    ptr = ptr->right;
    while (ptr->lthread == false)
        ptr = ptr->left;
    return ptr;
}
 
// Printing the threaded tree
void inorder(struct Node* root)
{
    if (root == NULL)
        printf("Tree is empty");
 
    // Reach leftmost Node
    struct Node* ptr = root;
    while (ptr->lthread == false)
        ptr = ptr->left;
 
    // One by one print successors
    while (ptr != NULL) {
        printf("%d ", ptr->info);
        ptr = inorderSuccessor(ptr);
    }
}
 
struct Node* inPred(struct Node* ptr)
{
    if (ptr->lthread == true)
        return ptr->left;
 
    ptr = ptr->left;
    while (ptr->rthread == false)
        ptr = ptr->right;
    return ptr;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseA(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // If Node to be deleted is root
    if (par == NULL)
        root = NULL;
 
    // If Node to be deleted is left
    // of its parent
    else if (ptr == par->left) {
        par->lthread = true;
        par->left = ptr->left;
    }
    else {
        par->rthread = true;
        par->right = ptr->right;
    }
 
    // Free memory and return new root
    free(ptr);
    return root;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseB(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    struct Node* child;
 
    // Initialize child Node to be deleted has
    // left child.
    if (ptr->lthread == false)
        child = ptr->left;
 
    // Node to be deleted has right child.
    else
        child = ptr->right;
 
    // Node to be deleted is root Node.
    if (par == NULL)
        root = child;
 
    // Node is left child of its parent.
    else if (ptr == par->left)
        par->left = child;
    else
        par->right = child;
 
    // Find successor and predecessor
    Node* s = inSucc(ptr);
    Node* p = inPred(ptr);
 
    // If ptr has left subtree.
    if (ptr->lthread == false)
        p->right = s;
 
    // If ptr has right subtree.
    else {
        if (ptr->rthread == false)
            s->left = p;
    }
 
    free(ptr);
    return root;
}
 
// Here 'par' is pointer to parent Node and 'ptr' is
// pointer to current Node.
struct Node* caseC(struct Node* root, struct Node* par,
                   struct Node* ptr)
{
    // Find inorder successor and its parent.
    struct Node* parsucc = ptr;
    struct Node* succ = ptr->right;
 
    // Find leftmost child of successor
    while (succ->lthread==false) {
        parsucc = succ;
        succ = succ->left;
    }
 
    ptr->info = succ->info;
 
    if (succ->lthread == true && succ->rthread == true)
        root = caseA(root, parsucc, succ);
    else
        root = caseB(root, parsucc, succ);
 
    return root;
}
 
// Deletes a key from threaded BST with given root and
// returns new root of BST.
struct Node* delThreadedBST(struct Node* root, int dkey)
{
    // Initialize parent as NULL and ptrent
    // Node as root.
    struct Node *par = NULL, *ptr = root;
 
    // Set true if key is found
    int found = 0;
 
    // Search key in BST : find Node and its
    // parent.
    while (ptr != NULL) {
        if (dkey == ptr->info) {
            found = 1;
            break;
        }
        par = ptr;
        if (dkey < ptr->info) {
            if (ptr->lthread == false)
                ptr = ptr->left;
            else
                break;
        }
        else {
            if (ptr->rthread == false)
                ptr = ptr->right;
            else
                break;
        }
    }
 
    if (found == 0)
        printf("dkey not present in tree\n");
 
    // Two Children
    else if (ptr->lthread == false && ptr->rthread == false)
        root = caseC(root, par, ptr);
 
    // Only Left Child
    else if (ptr->lthread == false)
        root = caseB(root, par, ptr);
 
    // Only Right Child
    else if (ptr->rthread == false)
        root = caseB(root, par, ptr);
 
    // No child
    else
        root = caseA(root, par, ptr);
 
    return root;
}
 
// Driver Program
int main()
{
    struct Node* root = NULL;
 
    root = insert(root, 20);
    root = insert(root, 10);
    root = insert(root, 30);
    root = insert(root, 5);
    root = insert(root, 16);
    root = insert(root, 14);
    root = insert(root, 17);
    root = insert(root, 13);
 
    root = delThreadedBST(root, 20);
    inorder(root);
 
    return 0;
}

Java

// Complete Java program to demonstrate deletion
// in threaded BST
import java.util.*;
class solution {
 
    static class Node {
        Node left, right;
        int info;
 
        // True if left pointer points to predecessor
        // in Inorder Traversal
        boolean lthread;
 
        // True if right pointer points to predecessor
        // in Inorder Traversal
        boolean rthread;
    };
 
    // Insert a Node in Binary Threaded Tree
    static Node insert(Node root, int ikey)
    {
        // Searching for a Node with given value
        Node ptr = root;
        Node par = null; // Parent of key to be inserted
        while (ptr != null) {
            // If key already exists, return
            if (ikey == (ptr.info)) {
                System.out.printf("Duplicate Key !\n");
                return root;
            }
 
            par = ptr; // Update parent pointer
 
            // Moving on left subtree.
            if (ikey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
 
            // Moving on right subtree.
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        // Create a new Node
        Node tmp = new Node();
        tmp.info = ikey;
        tmp.lthread = true;
        tmp.rthread = true;
 
        if (par == null) {
            root = tmp;
            tmp.left = null;
            tmp.right = null;
        }
        else if (ikey < (par.info)) {
            tmp.left = par.left;
            tmp.right = par;
            par.lthread = false;
            par.left = tmp;
        }
        else {
            tmp.left = par;
            tmp.right = par.right;
            par.rthread = false;
            par.right = tmp;
        }
 
        return root;
    }
 
    // Returns inorder successor using left
    // and right children (Used in deletion)
    static Node inSucc(Node ptr)
    {
        if (ptr.rthread == true)
            return ptr.right;
 
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        return ptr;
    }
 
    // Returns inorder successor using rthread
    // (Used in inorder)
    static Node inorderSuccessor(Node ptr)
    {
        // If rthread is set, we can quickly find
        if (ptr.rthread == true)
            return ptr.right;
 
        // Else return leftmost child of right subtree
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
        return ptr;
    }
 
    // Printing the threaded tree
    static void inorder(Node root)
    {
        if (root == null)
            System.out.printf("Tree is empty");
 
        // Reach leftmost Node
        Node ptr = root;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        // One by one print successors
        while (ptr != null) {
            System.out.printf("%d ", ptr.info);
            ptr = inorderSuccessor(ptr);
        }
    }
 
    static Node inPred(Node ptr)
    {
        if (ptr.lthread == true)
            return ptr.left;
 
        ptr = ptr.left;
        while (ptr.rthread == false)
            ptr = ptr.right;
        return ptr;
      
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseA(Node root, Node par,
                      Node ptr)
    {
        // If Node to be deleted is root
        if (par == null)
            root = null;
 
        // If Node to be deleted is left
        // of its parent
        else if (ptr == par.left) {
            par.lthread = true;
            par.left = ptr.left;
        }
        else {
            par.rthread = true;
            par.right = ptr.right;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseB(Node root, Node par,
                      Node ptr)
    {
        Node child;
 
        // Initialize child Node to be deleted has
        // left child.
        if (ptr.lthread == false)
            child = ptr.left;
 
        // Node to be deleted has right child.
        else
            child = ptr.right;
 
        // Node to be deleted is root Node.
        if (par == null)
            root = child;
 
        // Node is left child of its parent.
        else if (ptr == par.left)
            par.left = child;
        else
            par.right = child;
 
        // Find successor and predecessor
        Node s = inSucc(ptr);
        Node p = inPred(ptr);
 
        // If ptr has left subtree.
        if (ptr.lthread == false)
            p.right = s;
 
        // If ptr has right subtree.
        else {
            if (ptr.rthread == false)
                s.left = p;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseC(Node root, Node par,
                      Node ptr)
    {
        // Find inorder successor and its parent.
        Node parsucc = ptr;
        Node succ = ptr.right;
 
        // Find leftmost child of successor
        while (succ.lthread == false) {
            parsucc = succ;
            succ = succ.left;
        }
 
        ptr.info = succ.info;
 
        if (succ.lthread == true && succ.rthread == true)
            root = caseA(root, parsucc, succ);
        else
            root = caseB(root, parsucc, succ);
 
        return root;
    }
 
    // Deletes a key from threaded BST with given root and
    // returns new root of BST.
    static Node delThreadedBST(Node root, int dkey)
    {
        // Initialize parent as null and ptrent
        // Node as root.
        Node par = null, ptr = root;
 
        // Set true if key is found
        int found = 0;
 
        // Search key in BST : find Node and its
        // parent.
        while (ptr != null) {
            if (dkey == ptr.info) {
                found = 1;
                break;
            }
            par = ptr;
            if (dkey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        if (found == 0)
            System.out.printf("dkey not present in tree\n");
 
        // Two Children
        else if (ptr.lthread == false && ptr.rthread == false)
            root = caseC(root, par, ptr);
 
        // Only Left Child
        else if (ptr.lthread == false)
            root = caseB(root, par, ptr);
 
        // Only Right Child
        else if (ptr.rthread == false)
            root = caseB(root, par, ptr);
 
        // No child
        else
            root = caseA(root, par, ptr);
 
        return root;
    }
 
    // Driver Program
    public static void main(String args[])
    {
        Node root = null;
 
        root = insert(root, 20);
        root = insert(root, 10);
        root = insert(root, 30);
        root = insert(root, 5);
        root = insert(root, 16);
        root = insert(root, 14);
        root = insert(root, 17);
        root = insert(root, 13);
 
        root = delThreadedBST(root, 20);
        inorder(root);
    }
}
// This code is contributed by Arnab Kundu

C#

// Complete C# program to demonstrate deletion
// in threaded BST
using System;
 
class GFG {
 
    public class Node {
        public Node left, right;
        public int info;
 
        // True if left pointer points to predecessor
        // in Inorder Traversal
        public bool lthread;
 
        // True if right pointer points to predecessor
        // in Inorder Traversal
        public bool rthread;
    };
 
    // Insert a Node in Binary Threaded Tree
    static Node insert(Node root, int ikey)
    {
        // Searching for a Node with given value
        Node ptr = root;
        Node par = null; // Parent of key to be inserted
        while (ptr != null) {
            // If key already exists, return
            if (ikey == (ptr.info)) {
                Console.Write("Duplicate Key !\n");
                return root;
            }
 
            par = ptr; // Update parent pointer
 
            // Moving on left subtree.
            if (ikey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
 
            // Moving on right subtree.
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        // Create a new Node
        Node tmp = new Node();
        tmp.info = ikey;
        tmp.lthread = true;
        tmp.rthread = true;
 
        if (par == null) {
            root = tmp;
            tmp.left = null;
            tmp.right = null;
        }
        else if (ikey < (par.info)) {
            tmp.left = par.left;
            tmp.right = par;
            par.lthread = false;
            par.left = tmp;
        }
        else {
            tmp.left = par;
            tmp.right = par.right;
            par.rthread = false;
            par.right = tmp;
        }
 
        return root;
    }
 
    // Returns inorder successor using left
    // and right children (Used in deletion)
    static Node inSucc(Node ptr)
    {
        if (ptr.rthread == true)
            return ptr.right;
 
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        return ptr;
    }
 
    // Returns inorder successor using rthread
    // (Used in inorder)
    static Node inorderSuccessor(Node ptr)
    {
        // If rthread is set, we can quickly find
        if (ptr.rthread == true)
            return ptr.right;
 
        // Else return leftmost child of right subtree
        ptr = ptr.right;
        while (ptr.lthread == false)
            ptr = ptr.left;
        return ptr;
    }
 
    // Printing the threaded tree
    static void inorder(Node root)
    {
        if (root == null)
            Console.Write("Tree is empty");
 
        // Reach leftmost Node
        Node ptr = root;
        while (ptr.lthread == false)
            ptr = ptr.left;
 
        // One by one print successors
        while (ptr != null) {
            Console.Write("{0} ", ptr.info);
            ptr = inorderSuccessor(ptr);
        }
    }
 
    static Node inPred(Node ptr)
    {
        if (ptr.lthread == true)
            return ptr.left;
 
        ptr = ptr.left;
        while (ptr.rthread == false)
            ptr = ptr.right;
        return ptr;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseA(Node root, Node par,
                      Node ptr)
    {
        // If Node to be deleted is root
        if (par == null)
            root = null;
 
        // If Node to be deleted is left
        // of its parent
        else if (ptr == par.left) {
            par.lthread = true;
            par.left = ptr.left;
        }
        else {
            par.rthread = true;
            par.right = ptr.right;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseB(Node root, Node par,
                      Node ptr)
    {
        Node child;
 
        // Initialize child Node to be deleted has
        // left child.
        if (ptr.lthread == false)
            child = ptr.left;
 
        // Node to be deleted has right child.
        else
            child = ptr.right;
 
        // Node to be deleted is root Node.
        if (par == null)
            root = child;
 
        // Node is left child of its parent.
        else if (ptr == par.left)
            par.left = child;
        else
            par.right = child;
 
        // Find successor and predecessor
        Node s = inSucc(ptr);
        Node p = inPred(ptr);
 
        // If ptr has left subtree.
        if (ptr.lthread == false)
            p.right = s;
 
        // If ptr has right subtree.
        else {
            if (ptr.rthread == false)
                s.left = p;
        }
 
        return root;
    }
 
    // Here 'par' is pointer to parent Node and 'ptr' is
    // pointer to current Node.
    static Node caseC(Node root, Node par,
                      Node ptr)
    {
        // Find inorder successor and its parent.
        Node parsucc = ptr;
        Node succ = ptr.right;
 
        // Find leftmost child of successor
        while (succ.lthread == false) {
            parsucc = succ;
            succ = succ.left;
        }
 
        ptr.info = succ.info;
 
        if (succ.lthread == true && succ.rthread == true)
            root = caseA(root, parsucc, succ);
        else
            root = caseB(root, parsucc, succ);
 
        return root;
    }
 
    // Deletes a key from threaded BST with given root and
    // returns new root of BST.
    static Node delThreadedBST(Node root, int dkey)
    {
        // Initialize parent as null and ptrent
        // Node as root.
        Node par = null, ptr = root;
 
        // Set true if key is found
        int found = 0;
 
        // Search key in BST : find Node and its
        // parent.
        while (ptr != null) {
            if (dkey == ptr.info) {
                found = 1;
                break;
            }
            par = ptr;
            if (dkey < ptr.info) {
                if (ptr.lthread == false)
                    ptr = ptr.left;
                else
                    break;
            }
            else {
                if (ptr.rthread == false)
                    ptr = ptr.right;
                else
                    break;
            }
        }
 
        if (found == 0)
            Console.Write("dkey not present in tree\n");
 
        // Two Children
        else if (ptr.lthread == false && ptr.rthread == false)
            root = caseC(root, par, ptr);
 
        // Only Left Child
        else if (ptr.lthread == false)
            root = caseB(root, par, ptr);
 
        // Only Right Child
        else if (ptr.rthread == false)
            root = caseB(root, par, ptr);
 
        // No child
        else
            root = caseA(root, par, ptr);
 
        return root;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        Node root = null;
 
        root = insert(root, 20);
        root = insert(root, 10);
        root = insert(root, 30);
        root = insert(root, 5);
        root = insert(root, 16);
        root = insert(root, 14);
        root = insert(root, 17);
        root = insert(root, 13);
 
        root = delThreadedBST(root, 20);
        inorder(root);
    }
}
 
// This code has been contributed by 29AjayKumar

输出 :

10 13 14 16 17 5 30