<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
有些演演算法題裡有了這個概念,因為不知道這是什麼蒙圈了很久。
先序遍歷: root——>left——>right
中序遍歷: left—— root ——>right
後序遍歷 :left ——right——>root
先弄一個只有四個節點的小型二元樹,實際上這種小型二元樹應用不大。
二元樹的真正應用是二元搜尋樹,處理海量的資料。
程式碼很簡單,兩種遍歷的程式碼也差不多
#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("%dn",p->data); preorder(p->left); preorder(p->right); } } void inorder(Node *p){//中序遍歷 if(p!=NULL){ inorder(p->left); printf("%dn",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; }
講的非常清楚。
為了構建一顆便於查詢資料的樹形結構,我們規定 樹的節點的資料 value leftnode<value root <value rightnode
這樣的一棵樹叫做二元搜尋樹
為了簡單記憶我們就按函數中的根被存取的順序分為前序(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("%dn",node->data); preorder(node->left); preorder(node->right); } } void inorder(Node*node){ if(node!=NULL){ inorder(node->left); printf("%dn",node->data); inorder(node->right); } } void postorder(Node*node){ if(node!=NULL){ postorder(node->left); postorder(node->right); printf("%dn",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==%dn",h); int max_ele=max_e(tree.root); printf("max_element==%d",max_ele); return 0; }
看起來很長但是實際上原理很簡單,這是工程程式碼的特點,用陣列模擬雖然會簡單很多,但是無奈,兩種都要會呀……
陣列模擬版本:
const int N=2e5+10; int cnt[N];// 結點x的值val出現的次數; int lc[N],rc[N],sz[N];//結點x的左子結點和右子結點以及以x為節點的子樹大小 int val[N];//結點x儲存的數值 int n; void print(int o){ if(!o) return ; print(lc[o]); for(int i=1;i<=cnt[o];i++) printf("%dn",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) {//如果節點o對應的值就是v 退出迴圈 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) {//結點多於一個元素,--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); } //時間複雜度O(h) h為樹的高度 //1.查詢元素的排名 // 查詢一個元素的排名,首先從根節點跳到這個元素,若向右跳,答案加上 //左兒子結點的個數加上當前結點的個數,最後答案加上終點的左子樹的大小加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的元素 //根節點的排名取決於其左子樹的大小 //若其左子樹的大小大於等於k,則該元素在左子樹,若其左子樹大小在[k-cnt,k-1]則該元素為子樹的根節點。 //若其左子樹的大小小於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]; }
到此這篇關於C語言範例實現二元搜尋樹詳解的文章就介紹到這了,更多相關C語言二元搜尋樹內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45