網站首頁 編程語言 正文
遞歸建立二叉樹
二叉樹的結構體
typedef struct Node
{
int data;
Node* lchild;
Node* rchild;
}BiNode,*BiTree;
二叉樹顧名思義最多只有兩個子結點和一個數據域,既然是鏈式那么子結點定義為結點指針類型,數據域就可以根據需要設置了,可以是整型也可以是字符型。
二叉樹初始化
BiTree createBiTree(BiTree &T)
{
int d;
cin >> d;
if (d == 0)
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiNode));
T->data = d;
T->lchild = createBiTree(T->lchild);
T->rchild = createBiTree(T->rchild);
}
return T;
}
這個初始化函數的返回值為BiTree是一個結構體指針類型,用來返回初始化后的 T 二叉樹;整型數據d是用來給二叉樹的結點賦值的,當輸入0的時候,該結點為空結點;當結點的數據域不為零,給該結點動態分配內存空間,并把d賦值給T->data;然后就是對左右子樹的遞歸初始化了。
先序遍歷
void PreOrder(BiTree T)//先序
{
if (T)
{
cout << T->data<<" ";
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
先序遍歷就是先訪問根結點,在訪問左子樹,最后訪問右子樹,這里也寫成遞歸形式;先訪問當前結點的數據,再對左右子樹進行訪問。
中序遍歷
void InOrder(BiTree T)//中序
{
if (T != NULL)
{
PreOrder(T->lchild);
cout << T->data << " ";
PreOrder(T->rchild);
}
}
中序遍歷就是先訪問左子樹,在訪問根結點,最后訪問右子樹,這里也寫成遞歸形式;先訪問當前結點的左子樹的數據,再對該結點的數據進行訪問,最后對右子樹進行訪問。
后序遍歷
void PostOrder(BiTree T)//后序
{
if (T)
{
PreOrder(T->lchild);
PreOrder(T->rchild);
cout << T->data << " ";
}
}
后序遍歷就是先訪問左子樹,在訪問右子樹,最后訪問根結點,這里也寫成遞歸形式;先訪問當前結點的左子樹的數據,再對右子樹進行訪問,最后訪問根結點。
具體例題
參考上面的結構體,設計一個函數,要求能夠同時求出二叉樹中所有結點的的個數和二叉樹中數據為奇數的和;
我的思考:該函數傳入m和n兩個全局變量,使用引用傳遞;當樹不為空時,m++,n等于n加該結點數據域的值,接下來進行左右子樹的遞歸調用:
void countT(BiTree T, int &m, int &n)
{
if (T == NULL) return ;
if (T->data % 2 != 0) n += T->data;
m++;
countT(T->lchild, m, n);
countT(T->rchild, m, n);
}
從主函數中這樣調用:
int m = 0,n = 0;
BiTree T=NULL;
countT(T, m, n);
最后輸出m和n的值即可
效果截圖:
注意輸出的格式,必須是樹的形式,下面解析一下
輸入的格式
注意:輸入的格式必須是樹的先序遍歷形式,因為在這個程序中初始化二叉樹就是用的先序的方式
在這個二叉樹先序輸入數據:3 4 6 0 8 0 0 0 11 13 0 0 0
全部源碼
粘貼到C++編譯器就能使用
#include<iostream>
using namespace std;
typedef struct Node
{
int data;
Node* lchild;
Node* rchild;
}BiNode,*BiTree;
BiTree createBiTree(BiTree &T)
{
int d;
cin >> d;
if (d == 0)
T = NULL;
else
{
T = (BiTree)malloc(sizeof(BiNode));
T->data = d;
T->lchild = createBiTree(T->lchild);
T->rchild = createBiTree(T->rchild);
}
return T;
}
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 PostOrder(BiTree T)//后序
{
if (T)
{
PostOrder(T->lchild);
PostOrder(T->rchild);
cout << T->data << " ";
}
}
void countT(BiTree T, int &m, int &n)
{
if (T == NULL) return ;
if (T->data % 2 != 0) n += T->data;
m++;
countT(T->lchild, m, n);
countT(T->rchild, m, n);
}
int main()
{
int m = 0,n = 0;
BiTree T=NULL;
cout << "輸入先序遍歷結點,建立二叉樹" << endl;
T = createBiTree(T);
cout << "先序遍歷結果" << endl;
PreOrder(T);
cout << endl;
cout << "中序遍歷結果" << endl;
InOrder(T);
cout << endl;
cout << "后序遍歷結果" << endl;
PostOrder(T);
cout << endl;
countT(T, m, n);
cout << "結點個數為:" << m << endl;
cout << "數據為:" << n << endl;
}
總結
代碼不是很長,每一個功能都對應一個函數,希望大家可以迅速掌握二叉鏈的基本使用,加油!
如果覺得寫得好,記得點贊支持一下哦
原文鏈接:https://ylqb196.blog.csdn.net/article/details/125051841
相關推薦
- 2022-02-07 出現報錯nginx: [emerg] unknown directive nginx.htacces
- 2022-08-19 C#對桌面應用程序自定義鼠標光標_C#教程
- 2022-07-26 react如何添加less環境配置_React
- 2023-05-07 C++中的并行與并發基礎與使用詳解_C 語言
- 2022-07-13 常用類之包裝類和String類
- 2022-07-11 CentOS 7安裝SQL Server 2019
- 2022-11-07 Android?Framework如何實現Binder_Android
- 2022-07-21 CentOS 網絡設置修改
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支