树的常见问题编程

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;


BTreeAddCore(root1->left, root2->left, ret->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;
BTreeAddCore(root1->right, root2->right, ret->right);
if(ret->right != NULL)
ret->right->parent = ret;
}
}
}
BTreeNode<int>* BTreeAdd(BTreeNode<int>* root1, BTreeNode<int>* root2)
{
BTreeNode<int>* ret = new BTreeNode<int>;


BTreeAddCore(root1, root2, ret);


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>
void inOrderThreadCore(BTreeNode<T>* node, BTreeNode<T>*& pre)
{
if(node == NULL)
{
return ;
}
inOrderThreadCore(node->left, pre);
node->left = pre;
if(pre != NULL)
pre->right = node;
pre = node;
inOrderThreadCore(node->right, pre);
}
template <typename T>
BTreeNode<T>* inOrderThread(BTreeNode<T>* node)
{
BTreeNode<T>* pre = NULL;
inOrderThreadCore(node, pre);


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


return node;


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


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


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


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


inOrderThreadCore3(node ,head, tail);


return head;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值