Using system;
Using system. Collections. Generic;
Using system. text;
Namespace binarytree
{
Class Program
{
Static void main (string [] ARGs)
{
// User operation
}
}
// Definition: Binary Tree Storage Structure
Public class node <t>
{
Private t data; // data domain
Private node <t> lchild; // left child
Private node <t> rchild; // right child
// Constructor
Public node (T Val, node <t> LP, node <t> RP)
{
Data = val;
Lchild = LP;
Rchild = RP;
}
// Constructor
Public node (node <t> LP, node <t> RP)
{
Data = default (t );
Lchild = LP;
Rchild = RP;
}
// Constructor
Public node (T Val)
{
Data = val;
Lchild = NULL;
Rchild = NULL;
}
// Constructor
Public node (T Val)
{
Data = default (t );
Lchild = NULL;
Rchild = NULL;
}
// Data attributes
Public t data
{
Get
{
Return data;
}
Set
{
Data = value;
}
}
// Left child attributes
Public node <t> lchild
{
Get
{
Return lchild;
}
Set
{
Lchild = value;
}
}
// Right child attributes
Public node <t> rchild
{
Get
{
Return rchild;
}
Set
{
Rchild = value;
}
}
}
// Bitree of binary tree with no leading Node
Public class bitree <t>
{
Private node <t> head; // header reference
// Constructor
Public bitree ()
{
Head = NULL;
}
// Constructor
Public bitree (T Val)
{
Node <t> P = new node <t> (VAL );
Head = P;
}
// Constructor
Public bitree (T Val, node <t> LP, node <t> RP)
{
Node <t> P = new node <t> (Val, LP, RP );
Head = P;
}
// Header reference attribute
Public node <t> head
{
Get
{
Return head;
}
Set
{
Head = value;
}
}
// Determine whether it is an empty Binary Tree
Public bool isempty ()
{
If (Head = NULL)
{
Return true;
}
Else
{
Return false;
}
}
// Obtain the root node
Public node <t> root ()
{
Return head;
}
// Obtain the left child node of the node
Public node <t> getlchild (node <t> P)
{
Return P. lchild;
}
// Obtain the right child node of the node
Public node <t> getrchild (node <t> P)
{
Return P. rchild;
}
// Insert the left subtree of node P into a new node with the value of Val.
// The original left subtree becomes the left subtree of the new node.
Public void insertl (T Val, node <t> P)
{
Node <t> TMP = new node <t> (VAL );
TMP. lchild = P. lchild; // The original left subtree becomes the left subtree of the new node.
P. lchild = TMP; // The left child of P is the new node.
}
// Insert the right subtree of node P into a new node with the value of Val,
// The original right subtree becomes the right subtree of the new node.
Public void insertr (T Val, node <t> P)
{
Node <t> TMP = new node <t> (VAL );
TMP. rchild = P. rchild; // the original right subtree becomes the right subtree of the new node
P. rchild = TMP; // The right child of P is the new node.
}
// If P is not empty, delete the left subtree of P.
Public node <t> deletel (node <t> P)
{
If (P = NULL | (P. lchild = NULL ))
{
Return NULL;
}
Node <t> TMP = P. lchild;
P. lchild = NULL;
Return TMP;
}
// If P is not empty, delete the right subtree of P.
Public node <t> deleter (node <t> P)
{
If (P = NULL) | (P. rchild = NULL ))
{
Return NULL;
}
Node <t> TMP = P. rchild;
P. rchild = NULL;
Return TMP;
}
// Determine whether the node is a leaf node
Public bool isleaf (node <t> P)
{
If (P! = NULL) & (P. lchild = NULL) & (P. rchild = NULL ))
{
Return true;
}
Else
{
Return false;
}
}
// Tree traversal: Since the tree definition is recursive, The traversal algorithm is also implemented by color recursion.
// The original sequence is a B c d e f g h I j (the principle is from small to bottom, from left to right)
// 1. First traverse (DLR), the idea is: first access the root node, then traverse its left subtree first, and then traverse its right subtree first.
// Result: a B d h I e J C f g
Public void preorder (node <t> root)
{
// The root node is empty.
If (root = NULL)
{
Return;
}
// Step 1: process the root node
Console. writeline ("{0}", root. data );
// Step 2: traverse the left subtree
Preorder (root. lchild );
// Step 3: traverse the right subtree
Preorder (root. rchild );
}
// The concept of LDR is: first, the left subtree of the node is traversed in the middle order, then the root node is accessed, and then the right subtree is traversed in the middle order.
// Result: H Di B e J E A F C G
Public void inorder (node <t> root)
{
// The root node is empty.
If (root = NULL)
{
Return;
}
// Traverse the left subtree in the middle order
Inorder (root. lchild );
// Process the root node. Note: The root node is a node that can be used as the parent node.
Console. writeline ("{0}", root. data );
// Traverse the right subtree in the middle order.
Inorder (root. rchild );
}
// Post-sequential traversal (LRD): the basic idea is: first traverse the left subtree of the root node, then traverse the right subtree of the root node in a later order, and finally access the root node
// Result: h I d j e B f g C
Public void postorder (node <t> root)
{
// The root node is empty.
If (root = NULL)
{
Return;
}
// Traverse the left subtree in descending order
Postorder (root. lchild );
// Traverse the right subtree in descending order
Postorder (root. rchild );
// Process the root node
Console. writeline ("{0}", root. data );
}
// (4). Level order)
// Thought: because the order of the layered traversal nodes is first met, the node is first accessed, which is the same as the order of queue operations.
// Therefore, set a queue and reference the root node to join the queue during the hierarchical traversal. When the queue is not empty, perform the following three steps cyclically:
// (1). retrieve a node reference from the queue and access the node.
// (2). If the left subtree of the node is not empty, reference the left subtree of the node into the queue;
// (3) if the right subtree of the node is not empty, reference the right subtree of the node to the queue;
Public void levelorder (node <t> root)
{
// The root node is empty.
If (root = NULL)
{
Return;
}
// Set a node for storing sequence traversal in a queue
//... The definition class and operation class of the queue need to be referenced here.
}
}
}