【数据结构】二叉树递归算法代码总结

一、内容介绍

上一年备考数据结构中自己整理并验证过的二叉树递归算法。包括:
1、二叉树的创建;
2、二叉树的先、中、后序的递归遍历;
3、输出二叉树中所有度为2的节点;
4、输出二叉树中所有度为1的节点;
5、输出二叉树中所有度为0的节点;
6、输出二叉树中所有节点的个数;
7、输出二叉树中所有节点的度数;
8、输出二叉树的高度;
9、输出二叉树先序遍历中第三个节点值;
10、输出二叉树先序遍历中data域为65的节点;
11、输出二叉树中 右孩子指针将二叉树的叶子节点从左向右链接成的单链表;
12、输出二叉树根节点的右孩子节点的层数;

二、算法总结

2.1 二叉树结构

在这里插入图片描述

2.2 完整代码

#include<stdio.h>
#include<stdlib.h>
#include <iostream> 

using namespace std;
 


//二叉树的链式存储结构 
struct Tree{
	char data;   
//	int data;     //会自动转为ASCII码 
	struct Tree *lchild,*rchild;
};

//前序创建二叉树
void CreateTree(Tree **t) {
	char ch;
  	cin >> ch;
  	//递归的终止条件,如果输入#号创建空指针,说明当前节点左子树已创建完毕
  	if (ch == '#')
    	*t = NULL;

	else {
		*t = new Tree;
		(*t)->data = ch;
		CreateTree(&((*t)->lchild));
		CreateTree(&((*t)->rchild));
	}
}

//二叉树的三种遍历

void visit(Tree *t){
	//对结点的一些操作 
	cout << t->data << "  ";
} 



//先序 
void preorder(Tree *t){
	if(t!=NULL){
		visit(t);
		preorder(t->lchild);
		preorder(t->rchild);
	}
}

//中序 
void inorder(Tree *t){
	if(t!=NULL){
		inorder(t->lchild);
		visit(t);
		inorder(t->rchild);
	}
}

//后序 
void postorder(Tree *t){
	if(t!=NULL){
		postorder(t->lchild);
		postorder(t->rchild);
		visit(t);
	}
}

//计算二叉树的所有双分支节点(度为2)节点个数
int Degree_2(Tree *t){
    if(t==NULL){    //为空节点 
        return 0;
    }else if(t->lchild!=NULL && t->rchild!=NULL){    //为双分支节点 
    	return Degree_2(t->lchild)+Degree_2(t->rchild)+1;   //双分支节点个数=递归的双分支节点数+自己 
    }else{   //为单分支节点
    	return Degree_2(t->lchild)+Degree_2(t->rchild);    //双分支节点个数=递归的双分支节点数
    }
}

//计算二叉树的所有单分支节点(度为1)节点个数
int Degree_1(Tree *t){
    if(t==NULL){
        return 0;
    }else if(t->lchild!=NULL && t->rchild==NULL || t->lchild==NULL && t->rchild!=NULL){    //单分支节点 
    	return Degree_1(t->lchild)+Degree_1(t->rchild)+1;
    }else{
    	return Degree_1(t->lchild)+Degree_1(t->rchild);
    }
}

//计算二叉树的所有叶子节点(度为0)节点个数
int Degree_0(Tree *t){
    if(t==NULL){
        return 0;
    }else if(t->lchild==NULL && t->rchild==NULL){
    	return 1;
    }else{
    	return Degree_0(t->lchild)+Degree_0(t->rchild);
    }
}

//计算二叉树的所有节点个数
int n = 0;
int count(Tree *t){
	if(t!=NULL){
		++n;    //先序:根节点visit()改写,每次递归,n=n+1 
		count(t->lchild);
		count(t->rchild);
	}
	return n;
}


//计算二叉树高度 
int depth(Tree *t){
	if(t==NULL){
        return 0;    //递归到空树,返回0 
    }else{
    	int lh = depth(t->lchild);    //递归求左子树高 
    	int rh = depth(t->rchild);    //递归求右子树高 
		if(lh>=rh){
			return lh+1;
		}else{
			return rh+1;
		}
    } 
}


//把二叉树中所有节点的左右子树交换 
void swap(Tree *t) {
	if(t!=NULL){
		Tree *temp = new Tree();   //临时变量 
    	temp = t->lchild;
    	t->lchild = t->rchild;
    	t->rchild = temp;
    	swap(t->lchild);    //递归交换左 
    	swap(t->rchild);    //递归交换右 
    }
}


//求二叉树先序遍历中的第k个节点值 
int i = 0;
void find_k(Tree *t, int k){
	if(t!=NULL){
		++i;     //visit()
		if(k==i){
			cout<< t->data;
			return;
		}else{
			find_k(t->lchild,k);    //递归查左 
    		find_k(t->rchild,k);    //递归查右边
		}

	}
}

//查找二叉树data域等于key的节点是否存在,若存在,将q指向它,否则q为空 
void find_key(Tree *t,Tree *q,int key){
	if(t!=NULL){
		if(t->data==key){   //找到 
			q=t;
			cout<<q->data;
		}else{
		   	find_key(t->lchild,t,key);    //递归查左 
    		find_key(t->rchild,t,key);    //递归查右 
		}

    }
}

//利用节点的右孩子指针将一个二叉树的叶子节点从左向右链接成一个单链表(head指向第一个,tail指向最后一个) 
void link(Tree *t,Tree *head,Tree *tail){
	if(t!=NULL){
		if(t->lchild==NULL&&t->rchild==NULL){    //叶子节点 
			 if(head==NULL){    //还未指向时 
				head=t;
				tail=t;
			}
			tail->rchild=t;   //链接 
			tail=t;
			cout<<t->data<< "  ";
			
			
		}else{   //非叶子节点,递归 
			link(t->lchild,head,tail); 
			link(t->rchild,head,tail);  
		}
	} 
}


int h=0;
//求出指定节点在二叉排序树中的层次
//中序遍历二叉排序树得一个递增的序列 
int find_ceng(Tree *t,Tree *p) {
	if(t!=NULL){
		Tree *head=t;
		if(head!=NULL){
			while(head->data!=p->data){
				if(head->data<=p->data){
					head=head->rchild;
				}else{
					head=head->lchild;
				}
				++h;
			}
			return h;
		}
	} 
}

//求二叉树的带权路径长度

int wpl_inorder(Tree *t,int deep){
	int wpl=0;
	if(t!=NULL){ 
		if(t->lchild==NULL&&t->rchild==NULL){    //叶子节点
//			cout<<int(t->data); 
			wpl+=(int(t->data))*deep;
		}
		
//		cout<<"here2"; 
		if(t->lchild!=NULL)
			wpl_inorder(t->lchild,deep+1);   //递归左
		if(t->rchild!=NULL)
			wpl_inorder(t->rchild,deep+1);   //递归右
		return wpl;
	
	}
	

}


int main(){
	
	Tree *t;
	cout << "请按先序遍历的顺序创建二叉树,ABD##E##CF##G##" << endl;
	CreateTree(&t);
	cout << "先序遍历的结果为:";
	preorder(t) ;
	cout << endl;
	
	cout << "中序遍历的结果为:";
	inorder(t) ;
	cout << endl;

	cout << "后序遍历的结果为:";
	postorder(t) ;
	cout << endl;
	
	cout << "二叉树中所有度为2的节点:";
	cout << Degree_2(t);
	cout << endl; 
	
	cout << "二叉树中所有度为1的节点:";
	cout << Degree_1(t);
	cout << endl; 
	
	cout << "二叉树中所有度为0的节点:";
	cout << Degree_0(t);
	cout << endl; 
	
	cout << "二叉树的所有节点个数:";
	cout << count(t);
	cout << endl; 
	
	cout << "二叉树的高度:";
	cout << depth(t);
	cout << endl; 

	cout << "二叉树先序遍历中的第3个节点值 :";
	find_k(t,3);
	cout << endl; 

	cout << "二叉树先序遍历中data域等于65的节点 :";
	Tree *q = NULL;
	find_key(t,q,65);
	cout << endl; 
	
	cout << "右孩子指针将二叉树的叶子节点从左向右链接成一个单链表:";
	Tree *head = NULL;
	Tree *tail = NULL;
	link(t,head,tail);
	cout << endl; 
	
	cout << "求二叉树根节点的右孩子节点的层次:";
	Tree *p = t->rchild;
	cout << find_ceng(t,p);
	cout << endl; 
	
//	cout << "求二叉树的wpl:";
//	cout << wpl_inorder(t,0);
//	cout << endl; 
}


2.3 输出结果

在这里插入图片描述

三、Reference

大师兄的手把手教你写考研数据结构代码题:https://www.bilibili.com/video/BV1hQ4y1R7Tw

四、总结

这份总结分享给有需要的同学们。也希望2022年自己的努力,开花结果。

2023年1月3日于家中。

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微雨停了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值