【知识点】线索二叉树与查找二叉树
线索二叉树(TBT)
线索二叉树概念
新增标志域变量LTag和RTag,标志有无左子树和右子树,利用空链域存储节点的前驱和后继,以加快查找速度。
typedef struct TreeNode{
//数据域
int data;
//指针域
TreeNode *LChild,*RChild;
//标志域
bool LTag,RTag;
} *Node;
二叉树的线索化
分为前序线索化、中序线索化、后序线索化。
进行一次对应的遍历可以对其线索化。
#include <iostream>
using namespace std;
typedef struct TreeNode{
//数据域
int data;
//指针域
TreeNode *LChild,*RChild;
//标志域
bool LTag,RTag; //0表示子树存在,1表示不存在
} *Node;
Node CreateNode(int a){
Node NewNode = new TreeNode;
NewNode->data = a;
NewNode->LChild = NewNode->RChild = NULL;
NewNode->LTag = NewNode->RTag = 0; //默认都存在
return NewNode;
}
//中序线索化
void OrderTree(Node now){
static Node pre = NULL;
if(now == NULL)
return;
//处理左子树
OrderTree(now->LChild);
//设置前驱节点
if(now->LChild == NULL){
now->LTag = 1;
now->LChild = pre;
}
//设置后继节点
if(pre != NULL && pre->RChild == NULL){
pre->RTag = 1;
pre->RChild = now;
}
//记录pre
pre = now;
//处理右子树
OrderTree(now->RChild);
return;
}
//中序遍历并输出
void print(Node now){
if(now == NULL)
return;
//因为是中序遍历,可以直接找出最左边节点然后向右行进输出
//找最左节点
while(now != NULL && now->LTag == 0){
now = now->LChild;
}
//向右行进输出(串行访问)
while(now != NULL){
printf("%d",now->data);
if(now->RTag)
now = now->RChild;
else{
print(now->RChild);
break;
}
}
return;
}
int main(){
Node a = CreateNode(1);
a->LChild = CreateNode(2);
a->RChild = CreateNode(3);
a->LChild->LChild = CreateNode(4);
a->LChild->RChild = CreateNode(5);
a->RChild->LChild = CreateNode(6);
a->RChild->RChild = CreateNode(7);
OrderTree(a);
print(a);
return 0;
}
查找二叉树(BST)
查找二叉树概念
对于任意子树,其左子树所有关键字值小于根关键字值,其右子树所有关键字值大于根关键字值。
特征是中序遍历得到递增序列(二叉排序树)。
查找的时间复杂度为O(logN)
查找二叉树的查找
从根结点开始二分搜索即可。
Node Search(Node now,int key){
if(now == NULL)
return NULL;
if(key == now->data)
return now;
if(key > now->data)
return Search(now->RChild,key);
if(key < now->data)
return Search(now->LChild,key);
}
递归法找最小值。
Node Min(Node now){
if(now == NULL)
return NULL;
else if(now->LChild == NULL)
return now;
else
return Min(now->LChild);
}
循环法找最小值。
Node Min(Node now){
if(now == NULL)
return NULL;
while(now->LChild != NULL)
now = now->LChild;
return now;
}
最大值同理。(代码略)
查找二叉树的插入
插入操作的关键是找到要插入的位置。同样,我们用递归法找被插入的位置。
Node Insert(Node now,int a){
if(now == NULL) //生成子树
return CreateNode(a);
//查找对应位置
if(a < now->data)
now->LChild = Insert(now->LChild,a);
else if(a > now->data)
now->RChild = Insert(now->RChild,a);
return now;
}
查找二叉树的删除
分三种情况:
- 删除叶子节点
直接删除即可。 - 删除只有一个孩子节点的节点
用其孩子替代它的位置。 - 删除有两个孩子节点的节点
用其左子树的右端点或右子树左端点替代它的位置。
删除后,该树仍为查找二叉树。
替代时,要将材料节点递归地删除!
Node Delete(Node now,int a){
Node temp;
if(now == NULL)
return NULL;
if(a < now->data)
now->LChild = Delete(now->LChild,a);
else if(a > now->data)
now->RChild = Delete(now->RChild,a);
else //确定now为要删除的节点
{
if(now->LChild && now->RChild){ //有两个子节点
//寻找右子树左端点
temp = now->RChild;
while(temp->LChild) temp = temp->LChild;
//替换
now->data = temp->data;
now->RChild = Delete(now->RChild,now->data);
}
else if(!now->LChild){ //只有右子节点或没有子节点
temp = now;
now = now->RChild;
delete temp;
}
else{ //只有左子节点
temp = now;
now = now->LChild;
delete temp;
}
}
return now;
}

浙公网安备 33010602011771号