理解递归和二叉树的遍历
1、递归的特征
①执行时范围不断缩小,这样才能触底反弹
②终止条件判断在调用递归的前面
注意:
递归不一定需要显式地写return。隐式return的情况是:如果执行到函数的结尾,就会自动返回上一级。(这跟正常调用别的函数是一个道理)
理解递归最好的方式:
忘记这句话:“自己调用自己就是递归”
2、理解前中后序遍历
前序遍历基本过程
Java代码:
public static void preorder(TreeNode head){
if(head == null){
return ;
}
System.out.print(head.value + " ");
postOrderRecur(head.left);
postOrderRecur(head.right);
}
中序遍历基本过程
Java代码:
public static void inOrderRecur(TreeNode head) {
if(head == null){
return ;
}
inOrderRecur(head.left);
System.out.print(head.value + " ");
inOrderRecur(head.right);
}
后序遍历基本过程
Java代码:
public static void postOrderRecour(TreeNode head){
if(head == null){
return ;
}
postOrderRecur(head.left);
postOrderRecur(head.right);
System.out.print(head.value + " ");
}
题目:LeetCode144
给你二叉树的根结点root,返回它结点值的前序遍历。
此时LeetCode里提供的函数可能不能直接用来递归,可以自己再创建一个函数
Java代码:
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<Integer>();
preorder(root, res);
return res;
}
public void preorder(TreeNode root, List<Integer> res){
if(root == null){
return ;
}
res.add(root.val);
preorder(root.left, res);
preorder(root.right, res);
}
Python代码:
def preorderTraversal(self, root):
def preorder(root):
if not root:
return
res.append(root.val)
preorder(root.left)
preorder(root.right)
res = list()
preorder(root)
return res
C++代码:
public:
void preorder(TreeNode* root, vector<int> &res){
if(root == nullptr){
return ;
}
res.push_back(root->val);
preorder(root->left, res);
preorder(root->right, res);
}
vector<int> preorderTraversal(TreeNode* root) {
vector<int> res;
preorder(root, res);
return res;
}
二叉树的完整代码实现:
C++代码:
以下这个代码实在是太完美了,来自另外一个博主的代码,转载链接:https://blog.csdn.net/qq_46601680/article/details/120939004
#include <iostream>
using namespace std;
//数据结构
typedef struct BiTNode{
char data;
struct BiTNode *lchild;
struct BiTNode *rchild;
}BiTNode,*BiTree;
//先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T) {//二叉树的构造,用递归
char ch;
cin >> ch;
//当前结点为空
if (ch == '#') T = NULL;
else {
//当前结点不空
T = new BiTNode;
T->data = ch;
CreateBiTree(T->lchild);//构造左子树
CreateBiTree(T->rchild);//构造右子树
}
}
//递归先序遍历
void PreOrder(BiTree T){
if(T){
cout<<T->data<<" ";
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
//中序遍历
void InOrder(BiTree T){
if(T){
InOrder(T->lchild);
cout<<T->data<<" ";
InOrder(T->rchild);
}
}
//后序遍历
void SubOrder(BiTree T){
if(T){
SubOrder(T->lchild);
SubOrder(T->rchild);
cout<<T->data<<" ";
}
}
//复制二叉树
bool Copy(BiTree T, BiTree &NewT){
if(T == NULL){
NewT = NULL;
return false;
} else{
NewT = new BiTNode;
NewT->data = T->data;
Copy(T->lchild, NewT->lchild);
Copy(T->rchild,NewT->rchild);
}
return true;
}
//计算二叉树深度
int Depth(BiTree T){
if(T == NULL)
return 0;
else{
int m = Depth(T->lchild);
int n = Depth(T->rchild);
if(m>n)
return (m+1);
else
return (n+1);
}
}
//计算结点总数
int NodeCount(BiTree T){
if(T == NULL)
return 0;
else
return (NodeCount(T->lchild) + NodeCount(T->rchild) + 1);
}
//计算叶子节点数
int LeafCount(BiTree T){
if(T == NULL)
return 0;
if(T->lchild == NULL && T->rchild == NULL)
return 1;
else
return (LeafCount(T->lchild) + LeafCount(T->rchild));
}
int main() {
BiTree T,NewT;
cout<<"请按先序遍历顺序依次输入,空元素用#表示"<<endl;
CreateBiTree(T);
cout<<"先序遍历:";
PreOrder(T);
cout<<endl;
cout<<"中序遍历";
InOrder(T);
cout<<endl;
cout<<"后序遍历";
SubOrder(T);
cout<<endl;
cout<<"复制二叉树"<<endl;
if(Copy(T,NewT)) cout<<"复制成功"<<endl;
cout<<"二叉树的深度为:"<<Depth(T)<<endl;
cout<<"结点数:"<<NodeCount(T)<<endl;
cout<<"叶子节点数:"<<LeafCount(T)<<endl;
system("pause");
return 0;
}
本篇文章为原创,欢迎转载,请注明文章出处链接:https://blog.csdn.net/2301_79084755/article/details/136516519。技术类文章一般都有时效性,本人会不定期对自己的博客进行修正更新,因此请访问出处以查看本文的最新版本。