线索化借鉴https://blog.csdn.net/my_heart_/article/details/52086321
搜索树参考 https://www.icourse163.org/learn/ZJU-93001?tid=1003013004#/learn/content?type=detail&id=1004242206&sm=1
#include<iostream>
#include<cstring>
#define ElemType char
using namespace std;
typedef enum{ //枚举?emmm,之前不知道
Link,
Thread
}Tag;
typedef struct BiTreeNode{
BiTreeNode(const ElemType data)
:Data(data),
Left(NULL),
Right(NULL),
rTag(Link),
lTag(Link)
{}
ElemType Data;
BiTreeNode*Left,*Right;
Tag rTag,lTag;
}BiTreeNode;
class Thread_Tree{
//friend class Binary_Search_Tree;
public:
Thread_Tree(const ElemType* arr,size_t Size)
:pRoot(NULL),
Prev(NULL)
{
size_t index=0;
_CreateTree(pRoot,arr,Size,index);
}
protected:
void _CreateTree(BiTreeNode*&Root,
const ElemType*arr,size_t size,size_t&index)//注意Root,index存储改变
{ //取地址
if(!arr||size==0)
{
cout<<"error input"<<endl;
return;
}
if(index<size&&arr[index]!='#')
{
Root=new BiTreeNode(arr[index]); //先序建树
_CreateTree(Root->Left,arr,size,++index);
_CreateTree(Root->Right,arr,size,++index);
}
}
public:
void PreOrderThreading()
{
_PreOrderThreading(this->pRoot);
}
void PreOrder()
{
_PreOrder(this->pRoot);
}
protected:
void _PreOrderThreading(BiTreeNode*&Root)
{
if(!Root)return; //结束条件
if(!Root->Left) //没有左子树,Left指向前驱
{
Root->Left=Prev;
Root->lTag=Thread; //标记Left为线索
}
if(Prev&&!Prev->Right) //前驱存在且没有右子树
{ //则Right指向后继
Prev->Right=Root;
Prev->rTag=Thread; //Right为线索
}
Prev=Root; //作为下一次递归的前驱
if(Root->lTag==Link)
_PreOrderThreading(Root->Left); //左子树存在,线索化左子树
if(Root->rTag==Link)
_PreOrderThreading(Root->Right); //……
}
void _PreOrder(BiTreeNode*Root) //先序遍历
{
if(!Root)return;
auto pCur=Root;
while(pCur)
{
while(pCur->lTag==Link&&pCur->Left) //打印爸爸,直到最左
{
cout<<pCur->Data<<" ";
pCur=pCur->Left;
}
cout<<pCur->Data<<" "; //不要漏下最左边的结点
if(pCur->lTag==Thread)pCur=pCur->Right; //最左边完了,往右走
while(pCur)
{
if(pCur->Left&&pCur->lTag==Link)break; //如果右边的结点有左子树,
cout<<pCur->Data<<" "; //退出,遍历该左子树
pCur=pCur->Right;
}
}
}
private:
BiTreeNode*pRoot,*Prev;
};
class Binary_Search_Tree{
//friend class Thread_Tree;
public:
Binary_Search_Tree()
:Root(NULL)
{};
public:
BiTreeNode* Find(const ElemType X)
{
return _Find(X,this->Root);
}
BiTreeNode* FindMin()
{
return _FindMin(this->Root);
}
BiTreeNode* FindMax()
{
return _FindMax(this->Root);
}
void Insert(const ElemType X)
{
_Insert(X,this->Root);
}
void Delete(const ElemType X)
{
_Delete(X,this->Root);
}
protected:
BiTreeNode*_Find(const ElemType X,BiTreeNode*Root) //BST,左边小于右边
{ //小于向左边找,
if(!Root)return NULL; //大于向右边找
else if(X<Root->Data)
return _Find(X,Root->Left);
else if(X>Root->Data)
return _Find(X,Root->Right);
else
return Root;
}
BiTreeNode*_FindMin(BiTreeNode*Root) //最小的在最左边
{
if(!Root)return NULL;
else if(!Root->Left)
return Root;
else
return _FindMin(Root->Left);
}
BiTreeNode*_FindMax(BiTreeNode*Root) //……
{
if(Root)
{
while(Root->Right)Root=Root->Right;
}
return Root;
}
BiTreeNode*_Insert(const ElemType X,BiTreeNode*&Root)
{
if(!Root)
{
Root=new BiTreeNode(X);
//cout<<"successful"<<endl;
}
else
{
if(X<Root->Data)
Root->Left=_Insert(X,Root->Left); //换个思路?返回插入后左右结点
else
Root->Right=_Insert(X,Root->Right);
}
return Root;
}
BiTreeNode*_Delete(const ElemType X,BiTreeNode*&Root)
{
BiTreeNode*Tmp;
if(!Root)return NULL;
if(X<Root->Data)
Root->Left=_Delete(X,Root->Left);
else if(X>Root->Data)
Root->Right=_Delete(X,Root->Right);
else //找到待删除元素之后
{ /如果该结点有两个子树
if(Root->Left&&Root->Right) //用左子树最大值,
{ //或右子树最小值,
Tmp=_FindMin(Root->Right); //替换该结点
Root->Data=Tmp->Data; //并删除左右子树相应结点
Root->Right=_Delete(Root->Data,Root->Right); //结点在左树最右
/* //或右树最左
Tmp=FindMax(Root->Left); //不可能有两个孩子
Root->Data=Tmp->Data; //所以下面的else可以删除该结点
Root->Left=_Delete(Root->Data,Root->Left);
*/
}else{
Tmp=Root;
if(!Root->Left)Root=Root->Right; //没有左孩子,用右孩子替换结点
else if(!Root->Right)Root=Root->Left; //……
free(Tmp);
}
}
return Root;
}
private:
BiTreeNode*Root;
};
int main()
{
char a[]="012##3##4##";
Thread_Tree tree(a,strlen(a));
tree.PreOrderThreading();
tree.PreOrder();
cout<<endl<<"*******************"<<endl;
Binary_Search_Tree tree1;
tree1.Insert('a');
tree1.Insert('b');
tree1.Insert('e');
tree1.Insert('d');
cout<<"max: "<<tree1.FindMax()->Data<<endl;
cout<<"min: "<<tree1.FindMin()->Data<<endl;
cout<<"find b: "<<tree1.Find('b')->Data<<endl;
tree1.Delete('e');
cout<<"max after delete e: "<<tree1.FindMax()->Data<<endl;
return 0;
}