我们已经讨论过二进制线程二叉树。
在二进制线程树中的插入与在二进制树中的插入相似,但是在插入每个元素之后,我们将不得不调整线程。
二进制线程节点的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