【知识点】线索二叉树与查找二叉树

线索二叉树(TBT)

线索二叉树概念

新增标志域变量LTagRTag,标志有无左子树和右子树,利用空链域存储节点的前驱和后继,以加快查找速度。

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;
}

查找二叉树的删除

分三种情况:

  1. 删除叶子节点
    直接删除即可。
  2. 删除只有一个孩子节点的节点
    用其孩子替代它的位置。
  3. 删除有两个孩子节点的节点
    用其左子树的右端点或右子树左端点替代它的位置。

删除后,该树仍为查找二叉树。
替代时,要将材料节点递归地删除!

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;
}
posted @ 2025-01-15 10:44  Alkaid16  阅读(29)  评论(0)    收藏  举报