70、二叉树题目

单度结点删除:

编写一个函数用于删除单度结点,删除后,其唯一的子节点替代它的位置。

结点包含指向父结点的指针:

定义功能:delOdd1(node)

删除node为根结点的二叉树中的单度结点

delOdd1(node)=

return; node==NULL

parent=node->parent;parent->child=node->child;node->child->parent=parent;delOdd1(node->child); degree==1

delOdd1(node->left);delOdd1(node->right); degree==0or degree==2

结点中只包含左右孩子指针

定义功能:delOdd2(node) //node为结点指针的引用

删除node为根结点的二叉树中的单度结点

delOdd2(node)=

return ; node==NULL

node=node->child;delOdd(node); degree==1

delOdd2(node->left);delOdd2(node->right);degree==0 or degree==2

#include <iostream>
#include "BTree.h"
#include "BTreeNode.h"
#include "WSstring.h"
using namespace std;
using namespace WSlib;
template <typename T>
BTreeNode<T>* createTree()
{
static BTreeNode<int> ns[9];
for(int i=0;i<9;i++)
{
ns[i].value=i;
ns[i].parent=NULL;
ns[i].left=NULL;
ns[i].right=NULL;
}
ns[0].left=&ns[1];
ns[0].right=&ns[2];
ns[1].parent=&ns[0];
ns[2].parent=&ns[0];
ns[1].left=&ns[3];
ns[1].right=NULL;
ns[3].parent=&ns[1];
ns[2].left=&ns[4];
ns[2].right=&ns[5];
ns[4].parent=&ns[2];
ns[5].parent=&ns[2];
ns[3].left=NULL;
ns[3].right=&ns[6];
ns[6].parent=&ns[3];
ns[4].left=&ns[7];
ns[4].right=NULL;
ns[7].parent=&ns[4];
ns[5].left=&ns[8];
ns[5].right=NULL;
ns[8].parent=&ns[5];
return ns;
}
template <typename T>
void printInOrder(BTreeNode<T>* node)
{
if(node!=NULL)
{
printInOrder(node->left);
cout<<node->value<<" ";
printInOrder(node->right);
}
}
//删除包含父结点的单度结点
template<typename T>
BTreeNode<T>* delOdd1(BTreeNode<T>* node)
{
BTreeNode<T>* ret=NULL;
if(node!=NULL)
{
if(((node->left!=NULL)&&(node->right==NULL))||((node->left==NULL)&&(node->right!=NULL)))
{
BTreeNode<T>* parent=dynamic_cast<BTreeNode<T>*>(node->parent);
BTreeNode<T>* node_child=(node->left!=NULL)? node->left:node->right;
if(parent !=NULL) //根结点可能单度,那么他的parent就是空
{
BTreeNode<T>*& parent_child=(parent->left==node)?parent->left:parent->right;
parent_child=node_child;
node_child->parent=parent;
}
else
{
node_child->parent=NULL;//子孩子的父亲为空,node_child与parent断开
}
if(node->flag())
{
delete node;
}
ret=delOdd1(node_child);
}
else
{
delOdd1(node->left);
delOdd1(node->right);
ret=node;
}
}
return ret;
}
//删除只有左右孩子的单度结点
template <typename T>
void delOdd2(BTreeNode<T>*& node)//node 是c++引用
{
if(node!=NULL)
{
if(((node->left!=NULL)&&(node->right==NULL))||((node->left==NULL)&&(node->right!=NULL)))
{
BTreeNode<T>* node_child=(node->left!=NULL)?node->left:node->right;
if(node->flag())
{
delete node;
}
node=node_child;//node父结点中孩子的别名?老师这样讲,但是我感觉还是父结点,改动指针的引用就改了孩子?孩子的孩子复制给父亲的子指针。孩子的孩子复制给父亲的子指针。node不是一个指针,而是父结点中孩子指针的引用,而不是指向了孩子。引用与指针的区别,一个是就把孩子的指针复制给他,另一个是,引用了这个指针
delOdd2(node);
}
else
{
delOdd2(node->left);
delOdd2(node->right);
}
}
}
int main()
{
BTreeNode<int>* ns=createTree<int>();
printInOrder(ns);
cout<<endl;
//ns=delOdd1(ns);
delOdd2(ns);
printInOrder(ns);
cout<<endl;
/*带父指针的测试
int a[]={6,7,8};//验证parent指针处理好没
for(int i=0;i<3;i++)
{
TreeNode<int>* n=ns+a[i];//n代表叶节点
while(n!=NULL)
{
cout<<n->value<<" ";
n=n->parent;


}
cout<<endl;


}
cout<<endl;*/
return 0;
}

2题:中序线索化二叉树:编写一个函数用于中序线索化二叉树,不允许使用其他数据结构。

解法一:在中序遍历的同时进行线索化

思路:使用辅助指针,在中序遍历时指向当前结点的前驱结点,访问当前结点时,连接与前驱结点的先后次序。

定义功能:inOrderThread(node,pre)

node:根结点,也是中序访问的结点。

pre:为中序遍历时的前驱结点指针。

inOrderThread(node,pre)=

return; node==NULL

inOrderThread(node->left,pre);node->left=pre;pre->right=node;pre=node;inOrderThread(node->right,pre); node!=NULL

 解法二:中序遍历的结点次序正好是结点的水平次序

思路:使用辅助指针,指向转换后双向链表的头结点和尾节点,根结点与左右子树转换的双向链表连接,成为完整双向链表。

定义功能:inOrderThread(node,head,tail)

node:根结点,也是中序访问的结点。

head:转换成功后指向双向链表的首结点。

tail:转换成功后指向双链表的尾节点。

inOrderThread(node,head,pre)=

return; node==NULL

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

template <typename T>
void inOrderThread(BTreeNode<T>* node,BTreeNode<T>*& head,BTreeNode<T>*& tail)
{
if(node!=NULL)
{
BTreeNode<T>* h=NULL;
BTreeNode<T>* t=NULL;
inOrderThread(node->left,h,t);
node->left=t;
if(t!=NULL)
{
t->right=node;
}
head= (h !=NULL)? h:node;
h=NULL; //左子树遍历完要h,t赋值为空,要不然出错
t=NULL;
inOrderThread(node->right,h,t);
node->right=h;
if(h!=NULL)
{
h->left=node;
}
tail=(t!=NULL)? t:node;
}
}
template <typename T>
BTreeNode<T>* inOrderThread2(BTreeNode<T>* node)
{
BTreeNode<T>* head=NULL;
BTreeNode<T>* tail=NULL;
inOrderThread(node,head,tail);
return head;

}

ns=inOrderThread2(ns);// main中
printDualList(ns);

猜你喜欢

转载自blog.csdn.net/ws857707645/article/details/80657083