二叉树的部分操作

二叉树宽度

定义:以二叉链形式存储的二叉树,其结点之间路径的最大值称为树的宽度。

在这里插入图片描述
从这张图上可以得到,最远路径是 4 → 7 4\rightarrow7 47
容易想到,左子树深度的最大值加上右子树深度最大值不就是最远路径了吗?
调用求树深度的函数不就轻而易举?

int getDepth(BinTree T)
{
	int LH,RH,MAXH;
	if(T){
		LH=getDepth(T->Lchild);
		RH=getDetph(T->Rchild);
		MAH=LH>RH?LH:RH;
		return MAXH+1;
	}
	return 0;
}
int getWidth(BinTree T)
{
	int LH,RH;
	if(T){
		LH=getDepth(T->Lchild);
		RH=getDepth(T->Rchild);
		return LH+RH+1;
	}
	return 0;
}

但问题到这里就结束了吗?-----没那么简单
在这里插入图片描述
如果树是这种结构,上述代码的结果是3而该树的直径应为4。
思路:在遍历的过程中加入“全局”变量,记录全局最大距离,而不是经过根节点的最大深度
修改如下

int getDepth(BinTree T,int *MaxHeight)
{
	int LH,RH;
	if(T){
		LH=getDepth(T->Lchild,MaxHeight);
		RH=getDetph(T->Rchild,MaxHeight);
		*MaxHeight=max(LH+RH,*MaxHeight);
		return max(LH,RH)+1;
	}
	return 0;
}
int getWidth(BinTree T)
{
	int MaxHeight=0;
	getDepth(T,&MaxHeight);
	return MaxHeight;
}

去除二叉树叶子节点

BTNode* RemoveLeave(BTNode *BT)
{
	if(!BT)
		return NULL;
	else if(!BT->Left&&!BT->Right)
		return NULL;
	else{
		BTNode newBT=new BTNode;
		newBT=BT;
		newBT->Left= RemoveLeave(BTNode BT->Left);
		newBT->Right= RemoveLeave(BTNode BT->Right);
		return newBT;
	}
}

根据二叉树的后序和中序得出二叉树的前序

假如给定后序和中序如下

2315764
1234567

思路:
建立pre,in,post数组,preL,inL,postL分别对应当前子段数组的最左边的位置
将post当前子段的最后一个元素赋值给pre当前子段的第一个元素。
将区间划分成两部分后继续递归,则得到答案
在这里插入图片描述

void getans(int preL,int inL,int postL,int n) //根据后序得到前序
{
	if(n==0) return;  //当n=0时直接return
	if(n==1) {pre[preL]=post[postL];return;} //只有一个元素时
	int root=post[postL+n-1],i;  
	pre[preL]=root;	//最后一个元素赋值给第一个
	for(i=0;i<n;i++) if(in[inL+i]==root) break;  //根据中序划分
	int L=i,R=n-L-1;
	getans(preL+1,inL,postL,L);     //递归左半部分
	getans(preL+L+1,inL+L+1,postL+L,R); //递归右半部分
}


void getans(int preL,int inL,int postL,int n)//根据前序和中序得到后序
{
	if(n==0) return;
	if(n==1) {post[postL]=pre[preL];return;} //这里反序
	int root=pre[preL],i;  //只改这两步
	post[postL+n-1]=root;	//只改这两步
	for(i=0;i<n;i++) if(in[inL+i]==root) break;
	int L=i,R=n-L-1;
	getans(preL+1,inL,postL,L);
	getans(preL+L+1,inL+L+1,postL+L,R);
}

将二叉树的叶子结点从左到右形成链表

思路:中序遍历的应用,当遍历到BT结点时,连接左右孩子,递归。

LinkList head,pre=NULL;
LinkList InOrder(BinTree BT)
{
	if(BT){
	InOrder(BT->Left);
	if(!BT->Left&&!BT->Right){//叶子
		if(pre==NULL){
			head=BT;
			pre=BT;
		}else{
			pre->Right=BT;
			pre=BT;
		}
	} 
	InOrder(BT->Right);
	pre->Right=NULL;
	}
	return head;
}

二叉搜索树的应用

递归表示

typedef struct BinTree Position;
//查找
Position Find(ElemType X,BinTree BST)
{
	if(!BST) return NULL;
	if(BST->Data==X) return BST;
	else if(BST->Data>X) Find(X,BST->Left);
	else Find(X,BST->Right);
}

//插入值为X的结点
BinTree Insert(ElemType X,BinTree BST)
{
    if(!BST) {
        BST=(BinTree)malloc(sizeof(BinTree));
        BST->Data=X;
        BST->Left=BST->Right;
    }else if(X<BST->Data) BST->Left=Insert(X,BST->Left);
    else if(X>BST->Data) BST->Right=Insert(X,BST->Right);
    return BST;
}


//删除值为X的结点
BinTree Delete(ElemType X,BinTree BST)
{
    Position Tmp;
    if(!BST) printf("Error");
    else if(X<BST->Data)
        BST->Left=Delete(X,BST->Left);
    else if(X>BST->Data)
        BST->Right=Delete(X,BST->Right);
    else
        if(BST->Left&&BST->Right){
            Tmp=FindMin(X,BST->Right);  
            BST->Data=Tmp->Data;
            BST->Right=Delete(BST->Data,BST->Right);
        }else{/*只有1个孩子或无子结点*/
            Tmp=BST;
            if(!BST->Left)  //左边空,右儿子替代
                BST=BST->Right;
            else if(!BST->Right) 
                BST=BST->Left;
            free(Tmp);
        }
    return BST;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值