網(wǎng)站首頁 編程語言 正文
有些算法題里有了這個概念,因為不知道這是什么蒙圈了很久。
先序遍歷: root——>left——>right
中序遍歷: left—— root ——>right
后序遍歷 :left ——right——>root
先弄一個只有四個節(jié)點的小型二叉樹,實際上這種小型二叉樹應(yīng)用不大。
二叉樹的真正應(yīng)用是二叉搜索樹,處理海量的數(shù)據(jù)。
代碼很簡單,兩種遍歷的代碼也差不多
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
int data;
struct node *left;
struct node *right;
}Node;
void preorder(Node *p){//前序遍歷
if(p!=NULL){
printf("%d\n",p->data);
preorder(p->left);
preorder(p->right);
}
}
void inorder(Node *p){//中序遍歷
if(p!=NULL){
inorder(p->left);
printf("%d\n",p->data);
inorder(p->right);
}
}
int main(){
Node n1;
Node n2;
Node n3;
Node n4;
n1.data=15;
n2.data=32;
n3.data=44;
n4.data=17;
n1.left=&n2;
n1.right=&n3;
n2.left=&n4;
n2.right=NULL;
n3.left=NULL;
n3.right=NULL;
n4.left=NULL;
n4.right=NULL;
preorder(&n1);
puts(" ");
inorder(&n1);
// 15
// / \
// 32 44
// / \ / \
// 17
return 0;
}
二叉樹代碼實現(xiàn)
講的非常清楚。
為了構(gòu)建一顆便于查找數(shù)據(jù)的樹形結(jié)構(gòu),我們規(guī)定 樹的節(jié)點的數(shù)據(jù) value leftnode<value root <value rightnode
這樣的一棵樹叫做二叉搜索樹
為了簡單記憶我們就按函數(shù)中的根被訪問的順序分為前序(pre),中序(in),后序(post)
代碼主要涉及前中后序遍歷和求二叉搜索樹的高度,和二叉搜索樹的最大值的一共5中基本操作
#include<stdio.h>
#include<stdlib.h>
#define max(a,b) a>b?a:b
typedef struct node{
int data;
struct node *left;
struct node *right;
}Node;
typedef struct {
Node *root;
}Tree;
void insert(Tree*tree,int x){
Node *node;
node=(Node*)malloc(sizeof (Node));
node->data=x,node->left=NULL,node->right=NULL;
if(tree->root==NULL){
tree->root=node;
}else {
Node *temp=tree->root;
while(temp!=NULL){
if(x<temp->data){//如果左兒子的data<x ,考慮左邊
if(temp->left==NULL){
temp->left=node;
return ;
} else temp=temp->left;
}else { //如果右兒子的data>x ,考慮右邊
if(temp->right==NULL){
temp->right=node;
return ;
}else temp=temp->right;
}
}
}
}
void preorder(Node*node){//二叉樹的前序遍歷
if(node!=NULL){
printf("%d\n",node->data);
preorder(node->left);
preorder(node->right);
}
}
void inorder(Node*node){
if(node!=NULL){
inorder(node->left);
printf("%d\n",node->data);
inorder(node->right);
}
}
void postorder(Node*node){
if(node!=NULL){
postorder(node->left);
postorder(node->right);
printf("%d\n",node->data);
}
}
int get_height(Node *node){//遞歸求高度h=max(Heightleftsob,Heightrightson);
if(node==NULL){
return 0;
}else {
int m1=get_height(node->left);
int m2=get_height(node->right);
int m=max(m1,m2);
return m+1;
}
}
int max_e(Node*node){//遞歸求解最大值,max_e=max{root->data,max_leftson_e,max_rightson_e};
if(node==NULL){
return -0x3f3f3f3f;
}else {
int m1=max_e(node->left);
int m2=max_e(node->right);
int m=node->data;
return max(max(m1,m2),m);
}
}
int main(){
Tree tree;
tree.root=NULL;
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) {
int t;
scanf("%d",&t);
insert(&tree,t);
}
preorder(tree.root);
inorder(tree.root);
postorder(tree.root);
int h=get_height(tree.root);
printf("h==%d\n",h);
int max_ele=max_e(tree.root);
printf("max_element==%d",max_ele);
return 0;
}
看起來很長但是實際上原理很簡單,這是工程代碼的特點,用數(shù)組模擬雖然會簡單很多,但是無奈,兩種都要會呀……
數(shù)組模擬版本:
const int N=2e5+10;
int cnt[N];// 結(jié)點x的值val出現(xiàn)的次數(shù);
int lc[N],rc[N],sz[N];//結(jié)點x的左子結(jié)點和右子結(jié)點以及以x為節(jié)點的子樹大小
int val[N];//結(jié)點x存儲的數(shù)值
int n;
void print(int o){
if(!o) return ;
print(lc[o]);
for(int i=1;i<=cnt[o];i++) printf("%d\n",val[o]);
print(rc[o]);
}
int findmin(int o){
if(!lc[o]) return o;
return findmin(lc[o]);
}
int findmax(int o){
if(!rc[o]) return o;
return findmax(rc[o]);
}
void insert(int &o,int v){
if(!o) {
val[o=++n]=v;
cnt[o]=sz[o]=1;
lc[o]=rc[o]=0;
return ;
}
sz[o]++;
if(val[o]==v) {//如果節(jié)點o對應(yīng)的值就是v 退出循環(huán)
cnt[o]++;
return ;
}
if(val[o]>v) insert(lc[o],v);
if(val[o]<v) insert(rc[o],v);
}
int deletemin(int &o){
if(!lc[o]){
int u=0;
o=rc[o];
return u;//遞歸終點
}else {
int u=deletemin(lc[o]);//用左子樹的最大值替換他,然后將它刪除
sz[o]-=cnt[u];
return u;
}
}
void del(int &o,int v){
sz[o]--;
if(val[o]==v){
if(cnt[o]>1) {//結(jié)點多于一個元素,--cnt
cnt[o]--;
return ;
}
if(lc[o]&&rc[o]) o=deletemin(rc[o]);
else o=lc[o]+rc[o];
return ;
}
if(val[o]>v) del(lc[o],v);
if(val[o]<v) del(rc[o],v);
}
//時間復(fù)雜度O(h) h為樹的高度
//1.查找元素的排名
// 查找一個元素的排名,首先從根節(jié)點跳到這個元素,若向右跳,答案加上
//左兒子結(jié)點的個數(shù)加上當(dāng)前結(jié)點的個數(shù),最后答案加上終點的左子樹的大小加1
int query(int o,int v){
if(val[o]==v) return sz[lc[o]]+1;
if(val[o]>v) return query(lc[o],v);
if(val[o]<v) return query(rc[o],v)+sz[lc[o]]+cnt[o];
}
//2.查找排名為k的元素
//根節(jié)點的排名取決于其左子樹的大小
//若其左子樹的大小大于等于k,則該元素在左子樹,若其左子樹大小在[k-cnt,k-1]則該元素為子樹的根節(jié)點。
//若其左子樹的大小小于k-cnt,則稱該元素在右子樹中
int querykth(int o,int k){
if(sz[lc[o]>=k] ) return querykth(lc[o],k);
if(sz[lc[o]]<k-cnt[o]) return querykth(rc[o],k-lc[o]-cnt[o]);
return val[o];
}
原文鏈接:https://blog.csdn.net/weixin_61819021/article/details/124884378
相關(guān)推薦
- 2023-08-01 el-table-column 內(nèi)容不自動換行
- 2022-08-17 R語言學(xué)習(xí)VennDiagram包繪制韋恩圖示例_R語言
- 2022-01-16 jQuery 核心函數(shù)和動態(tài)更新員工表
- 2022-06-29 Qt?Design?Studio創(chuàng)建工程的實現(xiàn)方法_C 語言
- 2022-10-17 Go?WaitGroup及Cond底層實現(xiàn)原理_Golang
- 2022-04-02 Python+Tkinter繪制一個數(shù)字時鐘_python
- 2023-04-20 URL中的參數(shù)提取
- 2022-12-10 Flutter?狀態(tài)管理scoped?model源碼解讀_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支