树与二叉树专题

题目:顺序存储,求编号i和j的最近公共祖先

代码展示:
(抓住结构特征)

int zx(int arr[],int i,int j)
{
    while(i!=j)
    {
        if(i<j)
        {
            j = j/2;
        }
        else
        {
            i = i/2;
        }
    }
    return arr[i];
}

题目:若两棵二叉树不但树形相似,对于元素也相等,则称这两课树等价,设计算法,判断两棵二叉树是否等价

代码展示:
(递归思想)

int isTreeEqual(BiTree T1,BiTree T2)
{
    if(T1==NULL && T2==NULL)
    {
        return true;
    }
    else if(T1==NULL || T2==NULL)
    {
        return false;
    }
    else if(T1->data != T2->data)
    {
        return false;
    }
    else if(isTreeEqual(T1->lchild,T2->lchild)&&isTreeEqual(T1->rchild,T2->rchild))
    {
        return true;
    }
    else
    {
        return false;
    }
}

题目:判断二叉树是否平衡

代码展示:

bool JudgeAVL(BiTree T,int &h)
{
    int hl,hr;
    bool bl,br;
    if(T==NULL)
    {
        h = 0;
        return true;
    }
    if(T->lchild==NULL && T->rchild==NULL)
    {
        h = 1;
        return true;
    }
    bl = JudgeAVL(T->lchild,hl);
    br = JudgeAVL(T->rchild,hr);
    h = hl>hr?hl+1:hr+1;
    if(bl==false || br==false || hl-hr>1 || hr-hl>1)
    {
        return false;
    }
    else
    {
        return true;
    }
}

题目:求祖先和最近公共祖先

代码展示:

int Find_Ancestores(BiTree T,int x,int path[],int level,int &count)
{//采用先序遍历查找二叉树值为x的所有祖先,level是层次,初始化为1,
//用path记录路径,count 记录长度
    if(T!=NULL)
    {
        path[level]=T->data;
        if(T->data==x){count=level;return 1;}
        if(Find_Ancestores(T->lchild,x,path,level+1,count)) return 1;
        return Find_Ancestores(T->rchild,x,path,level+1,count);
    }
    return 0;
}
//求最近公共祖先
BiTree lowestCommonAncestor(BiTree T, BiTree p, BiTree q)
{//求以T为根的二叉树中,p结点和q结点的最近公共祖先
    if(T == NULL || T == p || T ==q) return T;
    BiTree left = lowestCommonAncestor(T->lchild, p, q);
    BiTree right = lowestCommonAncestor(T->rchild, p, q);
    if(left && right)
    {
        return T;
    }
    else
    {
        //最小公共祖先一定从左从右找到p和q,不然不是最小公共祖先
        return left==NULL? right : left;
    }
}

题目:设计算法删除所有结点

代码展示:

void Del(BiTree &T)
{//删除以T为根的二叉树的所有结点
	if(T!=NULL)
	{
		Del(T->lchild);
		Del(T->rchild);
		free(T);
	}
}

题目:设计算法,逆时针打印所有边界结点,边界结点要么是根结点,要么是叶节点,或者是一层的最左和最右结点,不重复打印

代码展示:

void setEdgeMap(BiTree T,int i,BiTree edgeMap[][2])
{//设置T为根的二叉树的最左边和最右边结点,用edgeMap存,i是下标
	if(T==NULL) return;
	edgeMap[i][0]=(edgeMap[i][0]==NULL)?T:edgeMap[i][0];
	edgeMap[i][1]=T;
	setEdgeMap(T->lchild,i+1,edgeMap);
	setEdgeMap(T->rchild,i+1,edgeMap);	
}

void printfLeafNotInMap(BiTree T,int level,BiTree edgeMap[][2])
{//打印非最左和最右的叶节点信息,T为根指针,level为层次
	if(T==NULL) return;
	if(T->lchild==NULL&&T->rchild==NULL&&
		T!=edgeMap[level][0]&&T!=edgeMap[level][1])
		printf("%c ",T->data);
	printfLeafNotInMap(T->lchild,level+1,edgeMap);
	printfLeafNotInMap(T->rchild,level+1,edgeMap);
}

void printfEdgeNode(BiTree T,int h,BiTree edgeMap[][2])
{//打印二叉树T的边界结点,h为树的高度
	if(T==NULL) return ;
	int i;
	setEdgeMap(T,0,edgeMap);
	for(i=0;i<h;i++) printf("%c ",edgeMap[i][0]->data);
	printfLeafNotInMap(T,o,edgeMap);
	for(i=h-1;i>=0;i--)
		if(edgeMap[i][0]!=edgeMap[i][i])
			printf("%c ",edgeMap[i][1]->data);
		
	printf("\n");
}

题目:设计算法,将二叉树的所有叶节点成为一颗树的右子女,或者连成一棵单链表

代码展示:

void CreateSList_Pre(BiTree T,BiTree &rear)
{//利用先序遍历,用尾插法将所有叶节点通过右子树连接起来
	if(T!=NULL)
	{
		if(T->lchild==NULL&&T->rchild==NULL)
		{
			rear->rchild=T;rear=T;
		}
		CreateSList_Pre(T->lchild,rear);
		CreateSList_Pre(T->rchild,rear);
	}
}
void CreateSList(BiTree T,BiTree &head)
{//将二叉树T的所有叶子结点用右子树连接起来,head为头结点
	if(T!=NULL)
	{
		head=(BiTree)malloc(sizeof(BiTNode));
		BiTNode *rear=head;
		CreateSList_Pre(T,rear);
		rear->rchild=NULL;
	}
}

题目:求非空二叉树结点间的最大距离,两结点间的距离,就是他们的路径长度

代码展示:

int posOrder(TreeNode* root, int &record)
{
    if (root == nullptr)
    {
        record = 0;
        return 0;
    }
    int maxfromLeft;
    int lmax = posOrder(root->left, maxfromLeft);

    int maxfromRight;
    int rmax = posOrder(root->right, maxfromRight);

    int curmax = maxfromLeft + maxfromRight;
    record = max(maxfromLeft, maxfromRight) + 1;
    return max(max(lmax, rmax), curmax);
}

题目:表达式树的输出和求值

代码展示:

int getValue(char x)
{//求值转换
    char op[maxsize]={'a','b','c','d','e','f','g','h','i'};
    int d[maxsize]={40,38,13,39,20,21,12,26,31};
    for(int i=0;i<10;i++)
    {
        if(op[i]==x)
        {
            break;
        }
        else
        {
            return d[i];
        }
    }
}

int Exp_Calc(BiTree T)
{//表达式树求值
	if(T==NULL) return 0;
	if(T->lchild==NULL&&T->rchild==NULL) return getValue(T);
	int lv,rv;
	if(T->lchild)
	{
		if(isOprator(T->lchild->data)) lv=Exp_Calc(T->lchild);
		else lv=getValue(T->lchild);
	}
	if(T->rchild)
	{
		if(isOprator(T->rchild->data)) rv=Exp_Calc(T->lchild);
		else rv=getValue(T->rchild);
	}
	switch(T->data)
	{
		case '+':return lv+rv;
		case '-':return lv-rv;
		case '*':return lv*rv;
		case '/':return lv/rv;
	}
}

题目:求任意两个结点的路径和路径长度

代码展示:

void PathLength_P_Q(BiTree T,int p,int q,int path[],int &n)
{//对以T为根的二叉树,求结点p和q之间的路径,n返回路径长度,path返回路径
	int i,j,k,pc,qc;
	int path1[maxsize],path2[maxsize];
	//Find_Ancestores(BiTree T,int x,int path[],int level,int &count)
	//采用先序遍历查找二叉树值为x的所有祖先,level是层次,初始化为1,count 初始化为0
	//用path记录路径,count 记录长度
	Find_Ancestores(T,p,path1,1,pc);
	Find_Ancestores(T,q,path2,1,qc);
	if(!pc||!qc){n=0;return;}
	for(i=0;i<pc&&i<qc;i++)
		if(path1[i]!=path2[i]) break;
	k=0;path[k++]=p;
	for(j=pc-1;j>=i-1;j--) path[k++]=path1[j];
	for(j=i;j<qc;j++) path[k++]=path2[j];
	path[k]=q;
	n=k;
}

题目:设计算法,求所有叶节点的带权路径长度之和。

代码展示:

//带权路径用sum标记,初始化为0
int sum = 0;
//h为高度,初始化为1
void daiquanlujing(BiTree T,int h)
{
    if(T!=NULL)
    {
        if(T->lchild==NULL && T->rchild==NULL)
        {
            sum = sum+(h-1)*T->data;//求带权路径公式
        }
        daiquanlujing(T->lchild,h+1);
        daiquanlujing(T->rchild,h+1);
    }
}

题目:二叉树采用子女-兄弟链表存储,设计算法层次遍历这棵树
在这里插入图片描述
代码展示:

void Tree(BiTree T)
{//T是树的子女兄弟存储,层次遍历这棵树
	BiTree Q[maxsize],p,q;
	int front=0,rear=0;
	Q[rear++]=T->lchild;
	while(front<rear)
	{
		p=Q[front++];
		q=p->lchild;
		while(q)
		{
			Q[rear++]=q;
			q=q->rchild;
		}
	}
}

题目:二叉树采用子女-兄弟链表存储,设计算法,求树的高度,度,叶节点个数等等

代码展示:

//求高度算法如下
int high(BiTree T)
{//T是树的子女兄弟存储,求T的高度h初始化为1
	BiTree p;
	int max;
	if(T==NULL) return 0;
	else if(T->lchild==NULL) return 1;
	else 
	{
		p=T->lchild;
		max=high(p);
		while(p)
		{
			p=p->rchild;
			if(high(p)>max)  max=high(p);
		}
		return max+1;
	}	
}

题目:找中序线索二叉树的p结点的直接后驱或前驱
注:
ltag为0时lchild域指示结点的左孩子,为1时指示结点的前驱
rtag为0是rchild域指示结点的右孩子,为1时指示结点的后继

代码展示:

ThreadTree  mid(ThreadTree p)
{//求中序线索化树T,p结点的直接前驱或者后驱
	if(p->rtag==1) return p->rchild;
	else 
	{
		p=p->rchild;
		while(p->ltag==0) p=p->lchild;
		return p;
	}
}

题目:交换二叉树的左右子树

代码展示:

void change(BiTree &T)
{//交换二叉树T的左右子树
	BiTree p;
	if(T)
	{
		p=T->lchild;
		T->lchild=T->rchild;
		T->rchild=p;
		change(T->lchild);
		change(T->rchild);
	}
}

题目:写出在中序线索二叉树里查找指定结点在其后序的前驱结点的算法

代码展示:

ThreadTree  mid(ThreadTree T,ThreadTree p)
{//求中序线索化树T,p结点的后序直接前驱或者后驱
	if(p->rtag==0) return p->rchild;
	else if(p->ltag==0) return p->lchild;
	else
	{
		while(p->ltag==1)
		{
			p=p->lchild;
		}
		if(p==T) return NULL;
		else return p->lchild;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值