线程二叉树
可以使用递归或使用辅助堆栈来完成二叉树的中序遍历。线程二叉树的想法是使中序遍历更快,并且无需堆栈和递归即可完成。通过使通常为 NULL 的所有正确子指针指向节点的中序后继节点(如果存在),可以使二叉树成为线程化的。
有两种类型的线程二叉树。
单线程:其中 NULL 右指针指向中序后继(如果后继存在)
双线程:左右 NULL 指针分别指向有序前驱和有序后继。前导线程对于反向中序遍历和后序遍历很有用。
线程对于快速访问节点的祖先也很有用。
下图显示了一个示例单线程二叉树。虚线代表线程。
线程节点的 C 表示
以下是单线程节点的 C 表示。
C
struct Node
{
int data;
struct Node *left, *right;
bool rightThread;
}
Java
static class Node
{
int data;
Node left, right;
boolean rightThread;
}
// This code contributed by aashish1995
Python3
class Node:
def __init__(self, data,rightThread):
self.data = data;
self.left = None;
self.right = None;
self.rightThread = rightThread;
# This code is contributed by umadevi9616
C#
public class Node
{
public int data;
public Node left, right;
public bool rightThread;
}
// This code is contributed by aashish1995
Javascript
C
// Utility function to find leftmost node in a tree rooted
// with n
struct Node* leftMost(struct Node* n)
{
if (n == NULL)
return NULL;
while (n->left != NULL)
n = n->left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
void inOrder(struct Node* root)
{
struct Node* cur = leftMost(root);
while (cur != NULL) {
printf("%d ", cur->data);
// If this node is a thread node, then go to
// inorder successor
if (cur->rightThread)
cur = cur->right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur->right);
}
}
Java
// Utility function to find leftmost node in a tree rooted
// with n
Node leftMost(Node n)
{
if (n == null)
return null;
while (n.left != null)
n = n.left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
static void inOrder(Node root)
{
Node cur = leftMost(root);
while (cur != null) {
System.out.printf("%d ", cur.data);
// If this node is a thread node, then go to
// inorder successor
if (cur.rightThread)
cur = cur.right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur.right);
}
}
// This code contributed by aashish1995
Python3
# Utility function to find leftmost Node in a tree rooted
# with n
def leftMost(n):
if (n == None):
return None;
while (n.left != None):
n = n.left;
return n;
# C code to do inorder traversal in a threaded binary tree
def inOrder(root):
cur = leftMost(root);
while (cur != None):
print(cur.data," ");
# If this Node is a thread Node, then go to
# inorder successor
if (cur.rightThread):
cur = cur.right;
else: # Else go to the leftmost child in right
# subtree
cur = leftmost(cur.right);
# This code is contributed by Rajput-Ji
C#
// Utility function to find leftmost node in a tree rooted
// with n
Node leftMost(Node n)
{
if (n == null)
return null;
while (n.left != null)
n = n.left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
static void inOrder(Node root)
{
Node cur = leftMost(root);
while (cur != null)
{
Console.Write("{0} ", cur.data);
// If this node is a thread node, then go to
// inorder successor
if (cur.rightThread)
cur = cur.right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur.right);
}
}
// This code is contributed by gauravrajput1
Javascript
线程节点的Java表示
以下是单线程节点的Java表示。
Java
static class Node
{
int data;
Node left, right;
boolean rightThread;
}
// This code contributed by aashish1995
Python3
class Node:
def __init__(self, data,rightThread):
self.data = data;
self.left = None;
self.right = None;
self.rightThread = rightThread;
# This code is contributed by umadevi9616
C#
public class Node
{
public int data;
public Node left, right;
public bool rightThread;
}
// This code is contributed by aashish1995
Javascript
由于右指针有两个用途,布尔变量 rightThread 用于指示右指针是指向右子节点还是中序后继节点。同样,我们可以为双线程二叉树添加 leftThread。
使用线程的中序遍历
以下是线程二叉树中的中序遍历代码。
C
// Utility function to find leftmost node in a tree rooted
// with n
struct Node* leftMost(struct Node* n)
{
if (n == NULL)
return NULL;
while (n->left != NULL)
n = n->left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
void inOrder(struct Node* root)
{
struct Node* cur = leftMost(root);
while (cur != NULL) {
printf("%d ", cur->data);
// If this node is a thread node, then go to
// inorder successor
if (cur->rightThread)
cur = cur->right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur->right);
}
}
Java
// Utility function to find leftmost node in a tree rooted
// with n
Node leftMost(Node n)
{
if (n == null)
return null;
while (n.left != null)
n = n.left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
static void inOrder(Node root)
{
Node cur = leftMost(root);
while (cur != null) {
System.out.printf("%d ", cur.data);
// If this node is a thread node, then go to
// inorder successor
if (cur.rightThread)
cur = cur.right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur.right);
}
}
// This code contributed by aashish1995
Python3
# Utility function to find leftmost Node in a tree rooted
# with n
def leftMost(n):
if (n == None):
return None;
while (n.left != None):
n = n.left;
return n;
# C code to do inorder traversal in a threaded binary tree
def inOrder(root):
cur = leftMost(root);
while (cur != None):
print(cur.data," ");
# If this Node is a thread Node, then go to
# inorder successor
if (cur.rightThread):
cur = cur.right;
else: # Else go to the leftmost child in right
# subtree
cur = leftmost(cur.right);
# This code is contributed by Rajput-Ji
C#
// Utility function to find leftmost node in a tree rooted
// with n
Node leftMost(Node n)
{
if (n == null)
return null;
while (n.left != null)
n = n.left;
return n;
}
// C code to do inorder traversal in a threaded binary tree
static void inOrder(Node root)
{
Node cur = leftMost(root);
while (cur != null)
{
Console.Write("{0} ", cur.data);
// If this node is a thread node, then go to
// inorder successor
if (cur.rightThread)
cur = cur.right;
else // Else go to the leftmost child in right
// subtree
cur = leftmost(cur.right);
}
}
// This code is contributed by gauravrajput1
Javascript
下图演示了使用线程的中序遍历。