C语言实例实现二叉搜索树详解

C语言实例实现二叉搜索树详解

目录

有些算法题里有了这个概念,因为不知道这是什么蒙圈了很久。

先序遍历: 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("%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; }

二叉树代码实现

讲的非常清楚。

为了构建一颗便于查找数据的树形结构,我们规定 树的节点的数据 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("%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; }

看起来很长但是实际上原理很简单,这是工程代码的特点,用数组模拟虽然会简单很多,但是无奈,两种都要会呀……

数组模拟版本:

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("%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) {//如果节点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语言二叉搜索树内容请搜索易知道(ezd.cc)以前的文章或继续浏览下面的相关文章希望大家以后多多支持易知道(ezd.cc)!

推荐阅读

    探探语言设置|探探怎么设置语言

    探探语言设置|探探怎么设置语言,,1. 探探怎么设置语言打开探探软件,然后就有消息提示的红点,点开就行了!其实这些软件都是挺简单的操作的,都是

    git设置编码|git语言设置

    git设置编码|git语言设置,,git设置编码点击cap4j搜索从git直接链接上拉代码。git语言设置Git是一个开源的分布式版本控制系统,可以有效、高

    区域语言设置|区域语言设置工具

    区域语言设置|区域语言设置工具,,区域语言设置工具你好,大致的方法如下,可以参考:1、按下键盘的windows 图标,再开始菜单中单击“设置”;出现的

    c4d语言设置|c4d汉语设置

    c4d语言设置|c4d汉语设置,,1. c4d汉语设置mac版的C4D是这样的,中文字体是有的,但是是以拼音的形式存在,比如黑体就是ht。中文字体以拼音方式

    电脑宣传语|电脑宣传语言

    电脑宣传语|电脑宣传语言,,1. 电脑宣传语言1.我做好了与你过一辈子的打算,也做好了你随时要走的准备,2.每段青春都会苍老,但我希望记忆里的你

    office语言设置|微软office语言设置

    office语言设置|微软office语言设置,,微软office语言设置一、首先点击桌面左下角“WIN键”。二、弹出选项内点击“所有程序”。三、接着点

    小米设置日语|小米设置日语语言

    小米设置日语|小米设置日语语言,,1. 小米设置日语语言MIUI系统文字目前只支持简体中文、繁体中文、英文、藏文和维吾尔文,不支持日文 2. 小

    易语言开发电脑系统|易语言电脑版

    易语言开发电脑系统|易语言电脑版,,1. 易语言电脑版首先编译——是将程序编译为exe文件,只能在有易语言的机子上运行,独立编译——是将程序