📜  线程二叉树|插入

📅  最后修改于: 2021-05-25 00:23:49             🧑  作者: Mango

我们已经讨论过二进制线程二叉树。
在二进制线程树中的插入与在二进制树中的插入相似,但是在插入每个元素之后,我们将不得不调整线程。
二进制线程节点的C表示形式:

struct Node
{
  struct Node *left, *right;
  int info;

  // True if left pointer points to predecessor 
  // in Inorder Traversal
  boolean lthread; 

  // True if right pointer points to successor 
  // in Inorder Traversal
  boolean rthread; 
};

在以下说明中,我们考虑了要插入的二进制搜索树(BST),因为插入是由BST中的某些规则定义的。
tmp为新插入的节点。插入期间可能存在三种情况:
情况1:插入空树
tmp的左右指针都将设置为NULL,新节点将成为根节点。

root = tmp;
tmp -> left = NULL;
tmp -> right = NULL;

情况2:当新节点作为左子节点插入时
在将节点插入其适当位置后,我们必须使其左线程和右线程分别指向有序的前任和后继。是有序后继节点。因此,新节点的左右线程将是-

tmp -> left = par ->left;
tmp -> right = par;

在插入之前,parent的左指针是一个线程,但是在插入之后,它将是指向新节点的链接。

par -> lthread = false;
par -> left = temp;

下面的示例显示一个节点作为其父节点的左子节点插入。

插入13之后

14的前任成为13的前任,因此13的左线程指向10。
13的后继者是14,所以13的右线程指向左孩子13。
14的左指针现在不是线程,它指向13的左孩子。
情况3:当新节点作为正确的子节点插入时
tmp的父级是其有序的前身。以前是父节点的有序继承人的节点现在是此节点tmp的有序继承人。因此,新节点的左右线程将是-

tmp -> left = par;
tmp -> right = par -> right;

在插入之前,parent的右指针是一个线程,但是在插入之后,它将是指向新节点的链接。

par -> rthread = false;
par -> right = tmp;

下面的示例显示一个节点被插入为其父节点的右子节点。

插入15后,

14的后继者成为15的后继者,因此15的右线程指向16
15的前任是14,所以15的左线程指向14。
14的右指针现在不是线程,它指向15的右子代。
在线程二进制搜索树中插入新节点的C++实现:
像标准BST插入一样,我们在树中搜索键值。如果已经存在密钥,则返回否则,新的密钥将插入到搜索终止的位置。在BST中,当找到键或到达NULL左指针或右指针时,搜索就会终止。在这里,除了第一个节点的左指针和最后一个节点的右指针之外,所有左,右NULL指针都被线程替换。因此,当我们到达NULL指针或线程时,搜索将失败。

C++
// Insertion in Threaded Binary Search Tree.
#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 successor
    // 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 rthread
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);
    }
}
 
// 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);
 
    inorder(root);
 
    return 0;
}


Java
// Java program Insertion in Threaded Binary Search Tree.
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 successor
    // 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 rthread
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);
    }
}
   
// 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);
   
    inorder(root);
} 
}
//contributed by Arnab Kundu


Python3
# Insertion in Threaded Binary Search Tree.
class newNode:
    def __init__(self, key):
     
        # True if left pointer points to
        # predecessor in Inorder Traversal
        self.info = key
        self.left = None
        self.right =None
        self.lthread = True
     
        # True if right pointer points to
        # successor in Inorder Traversal
        self.rthread = True
 
# Insert a Node in Binary Threaded Tree
def insert(root, ikey):
     
    # Searching for a Node with given value
    ptr = root
    par = None # Parent of key to be inserted
    while ptr != None:
         
        # If key already exists, return
        if ikey == (ptr.info):
            print("Duplicate Key !")
            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
    tmp = newNode(ikey)
 
    if par == None:
        root = tmp
        tmp.left = None
        tmp.right = None
    elif 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 rthread
def inorderSuccessor(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
def inorder(root):
    if root == None:
        print("Tree is empty")
 
    # Reach leftmost node
    ptr = root
    while ptr.lthread == False:
        ptr = ptr.left
 
    # One by one print successors
    while ptr != None:
        print(ptr.info,end=" ")
        ptr = inorderSuccessor(ptr)
 
# Driver Code
if __name__ == '__main__':
    root = None
 
    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)
 
    inorder(root)
     
# This code is contributed by PranchalK


C#
using System;
 
// C# program Insertion in Threaded Binary Search Tree. 
public class solution
{
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 successor 
    // in Inorder Traversal 
    public bool rthread;
}
 
// Insert a Node in Binary Threaded Tree 
public 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 rthread 
public 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 
public 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:D} ",ptr.info);
        ptr = inorderSuccessor(ptr);
    }
}
 
// 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);
 
    inorder(root);
}
}
 
  // This code is contributed by Shrikant13


输出
5 10 13 14 16 17 20 30