# 树的常见问题编程

template <typename T>

/*

struct BTreeNode
{
T val;
BTreeNode* parent;
BTreeNode* left;
BTreeNode* right;

};

*/

//先序遍历二叉树

template <typename T>

void preTrav(BTreeNode<T>* p)
{
if(p != NULL)
{
cout << p->val << "  ";
preTrav(p->left);
preTrav(p->right);
}
}

//删除度为 1 的结点(包含指向父结点的指针)
//此处root的结构也会被修改
BTreeNode<int>* DeleteOdd1(BTreeNode<int>* root)
{
BTreeNode<int>* pNode = root;
BTreeNode<int>* ret = NULL;
if(root != NULL)
{
if((pNode->left==NULL && pNode->right!=NULL) ||
(pNode->left!=NULL && pNode->right==NULL))
{
BTreeNode<int>* pNode_child = (pNode->left == NULL) ? pNode->right : pNode->left;
BTreeNode<int>* pNode_parent = pNode->parent;

if(pNode_parent != NULL)
{
BTreeNode<int>*& pParent_child = (pNode_parent->left == pNode) ? pNode_parent->left : pNode_parent->right;
pParent_child = pNode_child;
pNode_child->parent = pNode_parent;
}
else
{
pNode_child->parent = NULL;
}
ret = DeleteOdd1(pNode_child);
delete pNode;
}
else
{
DeleteOdd1(pNode->left);
DeleteOdd1(pNode->right);

ret = pNode;
}
}
return ret;
}
//删除度为 1 的结点(不包含指向父结点的指针)
void DeleteOdd2(BTreeNode<int>*& pNode)
{
if(pNode != NULL)
{
if((pNode->left==NULL && pNode->right!=NULL) ||
(pNode->left!=NULL && pNode->right==NULL))
{
BTreeNode<int>* pNode_child = (pNode->left == NULL) ? pNode->right : pNode->left;
delete pNode;

pNode = pNode_child;

DeleteOdd2(pNode);
}
else
{
DeleteOdd2(pNode->left);
DeleteOdd2(pNode->right);
}
}
}
//克隆二叉树
BTreeNode<int>* CloneBTree(BTreeNode<int>* pNode)
{
if(pNode == NULL)
return NULL;
BTreeNode<int>* ret = new BTreeNode<int>;

ret->val = pNode->val;

ret->left = CloneBTree(pNode->left);
ret->right = CloneBTree(pNode->right);
//指定父结点
if(ret->left != NULL)
{
ret->left->parent = ret;
}
if(ret->right != NULL)
{
ret->right->parent = ret;
}

return ret;
}

//比较两棵二叉树是否相等
bool BTreeEqual(BTreeNode<int>* root1, BTreeNode<int>* root2)
{
if(root1==NULL && root2==NULL)
return true;
if((root1==NULL && root2!=NULL) || (root1!=NULL && root2==NULL))
return false;
if(root1->val != root2->val)
return false;
bool b1 = BTreeEqual(root1->left, root2->left);
bool b2 = BTreeEqual(root1->right, root2->right);

return (b1 && b2);
}
//二叉树相加
void BTreeAddCore(BTreeNode<int>* root1, BTreeNode<int>* root2, BTreeNode<int>*& ret)
{
if(root1 == NULL && root2 == NULL)
return ;
if(root1==NULL || root2 ==NULL)
ret = root1==NULL ? root2 : root1;
else
{
ret->val = root1->val + root2->val;
if(root1->left !=NULL || root2->left !=NULL)
{
BTreeNode<int>* Left = new BTreeNode<int>;
Left->right = NULL;
Left->left = NULL;
Left->val = 0;
ret->left = Left;

if(ret->left != NULL)
ret->left->parent = ret;
}
if(root1->right!=NULL || root2->right!=NULL)
{
BTreeNode<int>* Right = new BTreeNode<int>;
Right->right = NULL;
Right->left = NULL;
Right->val = 0;
ret->right = Right;
if(ret->right != NULL)
ret->right->parent = ret;
}
}
}
{
BTreeNode<int>* ret = new BTreeNode<int>;

return ret;
}
//线索化二叉树(利用队列)
template <typename T>
void preTrav(BTreeNode<T>* p, queue<BTreeNode<T>*>& q)
{
if(p != NULL)
{
q.push(p);
preTrav(p->left, q);
preTrav(p->right,q);
}
}
template <typename T>
BTreeNode<T>* LineBTree(queue<BTreeNode<T>*> q)
{
BTreeNode<int>* pre = NULL;
BTreeNode<int>* temp = NULL;
if(q.size() == 1)

temp = q.front();
temp->left = NULL;
temp->right = NULL;
return temp;
}
BTreeNode<int>* ret = q.front();
while(q.size()>1)
{
temp = q.front();
temp->left = pre;

q.pop();
temp->right = q.front();

pre = temp;
}
temp = q.front();
q.pop();

temp->left  = pre;
temp->right = NULL;

return ret;
}
//线索化二叉树_中序(不借用辅助空间)
template <typename T>
{
if(node == NULL)
{
return ;
}
node->left = pre;
if(pre != NULL)
pre->right = node;
pre = node;
}
template <typename T>
{
BTreeNode<T>* pre = NULL;

while((node != NULL) && (node->left  != NULL))
node = node->left;

return node;

}
//线索化二叉树_中序(利用两个指针)
template <typename T>
{
if(node != NULL)
{
BTreeNode<T>* h=NULL;
BTreeNode<T>* t=NULL;
if(t != NULL)
t->right = node;
node->left = t;

head = (h != NULL) ? h : node;

if(h != NULL)
h->left = node;
node->right = h;

tail = (t != NULL) ? t : node;
}
}
template <typename T>
{
BTreeNode<T>* tail=NULL;