二叉树的使用

Posted 我的头发可没乱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的使用相关的知识,希望对你有一定的参考价值。

C++

01

二叉树的创建和查找

#include<stdio.h>#include<stdlib.h>#include<time.h>typedef struct node{ //节点数据类型int data;struct node *lchild,*rchild;}Tnode;void insertTree(Tnode **r,int data){ //插入二叉排序树if(*r==NULL){ //如果树为空,则建树*r=(Tnode *)malloc(sizeof(Tnode));(*r)->data = data;(*r)->lchild=NULL;(*r)->rchild=NULL;}else if(data<(*r)->data) //当前值小于根结点,建左子树insertTree(&((*r)->lchild),data);else if(data>(*r)->data) //当前值大于根结点,建右子树insertTree(&((*r)->rchild),data);}void Creatree(Tnode **r,int a[],int n){ //调用插入函数,实现二叉排序树的创建int i;for(i=0;i<n;i++)insertTree(&(*r),a[i]);}int GetHeight(Tnode *r){ //定义统计二叉树的高度的函数int hl, hr, max;if (r!= NULL){hl = GetHeight(r->lchild); //求左子树高度hr = GetHeight(r->rchild); //求右子树高度max = hl > hr ? hl : hr;return (max + 1);}else return 0;}void outleaf(Tnode *r){ //定义输出二叉树的叶子节点的函数if(r==0) return ;else if(r->lchild==NULL&&r->rchild==NULL) //节点的左右子树同时为空,即为叶子printf("%d ",r->data);outleaf(r->lchild) ;outleaf(r->rchild) ;}void inorder(Tnode *r){ //定义实现中序遍历的函数if(r){inorder(r->lchild);printf("%d ",r->data);inorder(r->rchild);}}int main(){srand(time(NULL));Tnode *r=NULL;int DataCount,Maxdata,i,j;int *arr;while(1) //死循环,不得到正确输入不退出{printf(" 请输入 DataCount:");scanf("%d",&DataCount);printf(" 请输入 Maxdata:");scanf("%d",&Maxdata);if(DataCount>=10&&DataCount<=20&&Maxdata>=50&&Maxdata<=100) break;printf(" 输入不正确,请重新输入 ! 
");fflush(stdin); //清空输入}if((arr=(int *)malloc(DataCount*sizeof(int)))==NULL) //申请动态数组{printf(" 分配内存空间失败,程序退出! ");return 0;}for(i=0;i<DataCount;i++) { //向申请成功的数组中赋值arr[i]=rand()%(Maxdata+1);for(j=0;j<i;j++) //保证随机数不重复if(arr[i]==arr[j])i--;}printf(" 输出不重复的数据序列: 
");for(i=0;i<DataCount;i++) //输出不重复的数据序列printf("%d 	",arr[i]);Creatree(&r,arr,i);printf(" 输出二叉树的高度: 
");printf("%d
",GetHeight(r)); //输出二叉树的高度printf(" 输出二叉树的叶子节点 : 
");outleaf(r); //输出二叉树的叶子节点printf("
");printf(" 输出中序遍历序列: 
");inorder(r); //输出中序遍历序列printf("
");free(arr); //使用完后要释放所申请的空间return 0;}


02

二叉树的查找和删除

#include<stdio.h>#include<stdlib.h>#include<time.h>#include<string.h>typedef struct node{ //节点数据类型int data;struct node *lchild,*rchild;}Tnode;Tnode *mycopy(Tnode*r){ //二叉树的复制if(!r) return NULL;Tnode*copyr=(Tnode*)malloc(sizeof(Tnode));copyr->data=r->data;copyr->lchild=mycopy(r->lchild);copyr->rchild=mycopy(r->rchild);return copyr;};Tnode *search(Tnode *r,int key){ //在二叉排序树中查找值为 key 的节点if(r==NULL){printf(" 没有找到! ");return NULL;}else if(r!=NULL&&key==r->data){printf("Find it ! 
");printf(" 输出数据在内存中的地址: ");printf("%d",&r);return r;}else if(key<r->data)return search(r->lchild,key);else if(key>r->data)return search(r->rchild,key);}//获得其父节点Tnode *getFather(Tnode *r, Tnode *s){Tnode *sf;if(r==NULL||r==s)sf=NULL;else {if(s==r->lchild||s==r->rchild)sf= r;else if(s->data > r->data)sf=getFather(r->rchild,s);elsesf=getFather(r->lchild,s);}return sf;}//二叉树删除void DeleteNode(Tnode *r,int key){Tnode *L,*LL; //在删除左右子树都有的结点时使用;Tnode *p=r;Tnode *parent=r;int child=0; //0 表示左子树, 1 表示右子树;if(!r) //如果排序树为空,则退出;return ;while(p) //二叉排序树有效;{if(p->data==key){if(!p->lchild&&!p->rchild) //叶结点 (左右子树都为空 );{if(p==r) //被删除的结点只有根结点;free(p);else if(child==0){parent->lchild=NULL; //设置父结点左子树为空;free(p); //释放结点空间;}else //父结点为右子树;{parent->rchild=NULL; //设置父结点右子树为空;free(p); //释放结点空间;}}else if(!p->lchild) //左子树为空,右子树不为空;{if(child==0) //是父结点的左子树;parent->lchild=p->rchild;else //是父结点的右子树;parent->rchild=p->rchild;free(p); //释放被删除的结点;}else if(!p->rchild) //右子树为空,左子树不为空;{if(child==0) //是父结点的左子树;parent->lchild=p->lchild;else //是父结点的右子树;parent->rchild=p->lchild;free(p); //释放被删除的结点;}else{LL=p; //保存左子树的结点;L=p->rchild; //从当前结点的右子树进行查找;if(L->lchild) //左子树不为空;{LL=L;L=L->lchild; //查找左子树;p->data=L->data; //将左子树的数据保存到被删除结点;LL->lchild=L->lchild; //设置父结点的左子树指针为空;for(;L->lchild;L=L->lchild);L->lchild=p->lchild;p->lchild=NULL;}else{p->data=L->data;LL->rchild=L->rchild;}}p=NULL;}else if(key<p->data) //需删除记录的关键字小于结点的数据;{ //要删除的结点 p 是 parent 的左子树;child=0; //标记在当前结点左子树;parent=p;//保存当前结点作为父结点;p=p->lchild; //查找左子树;}else //需删除记录的关键字大于结点的数据;{ //要删除的结点 p 是 parent 的右子树;child=1; //标记在当前结点右子树查找;parent=p; //保存当前结点作为父结点;p=p->rchild; //查找右子树;}}}void insertTree(Tnode **r,int data){ //插入二叉排序树if(*r==NULL){ //如果树为空,则建树*r=(Tnode *)malloc(sizeof(Tnode));(*r)->data = data;(*r)->lchild=NULL;(*r)->rchild=NULL;}else if(data<(*r)->data) //当前值小于根结点,建左子树insertTree(&((*r)->lchild),data);else if(data>(*r)->data) //当前值大于根结点,建右子树insertTree(&((*r)->rchild),data);}void Creatree(Tnode **r,int a[],int n){ //调用插入函数,实现二叉排序树的创建int i;for(i=0;i<n;i++)insertTree(&(*r),a[i]);}int GetHeight(Tnode *r){ //定义统计二叉树的高度的函数int hl, hr, max;if (r!= NULL){hl = GetHeight(r->lchild); //求左子树高度hr = GetHeight(r->rchild); //求右子树高度max = hl > hr ? hl : hr;return (max + 1);}else return 0;}void outleaf(Tnode *r){ //定义输出二叉树的叶子节点的函数if(r==0) return ;else if(r->lchild==NULL&&r->rchild==NULL) //节点的左右子树同时为空,即为叶子printf("%d ",r->data);outleaf(r->lchild) ;outleaf(r->rchild) ;}void inorder(Tnode *r){ //定义实现中序遍历的函数if(r){inorder(r->lchild);printf("%d ",r->data);inorder(r->rchild);}}int main(){srand(time(NULL));Tnode *r=NULL,*copyr=NULL,*r1,*r2;int DataCount,Maxdata,i,j,k,m,key,key1;int *arr;while(1) //死循环,不得到正确输入不退出{printf(" 请输入 DataCount:");scanf("%d",&DataCount);printf(" 请输入 Maxdata:");scanf("%d",&Maxdata);if(DataCount>=10&&DataCount<=20&&Maxdata>=50&&Maxdata<=100) break;printf(" 输入不正确,请重新输入 ! 
");fflush(stdin); //清空输入}if((arr=(int *)malloc(DataCount*sizeof(int)))==NULL) //申请动态数组{printf(" 分配内存空间失败,程序退出! ");return 0;}for(i=0;i<DataCount;i++) //向申请成功的数组中赋值{arr[i]=rand()%(Maxdata+1);for(j=0;j<i;j++) //保证随机数不重复if(arr[i]==arr[j])i--;}printf(" 输出不重复的数据序列: 
");for(i=0;i<DataCount;i++) //输出不重复的数据序列printf("%d 	",arr[i]);Creatree(&r,arr,i);printf(" 输出源二叉树的高度: ");printf("%d
",GetHeight(r)); //输出源二叉树的高度printf(" 输出源二叉树的叶子节点 : ");outleaf(r); //输出源二叉树的叶子节点printf("
");printf(" 输出源二叉树中序遍历序列: ");inorder(r); //输出源二叉树中序遍历序列printf("
");copyr=mycopy(r); //从源二叉树拷贝二叉树副本printf(" 输出二叉树副本中序遍历序列: ");inorder(copyr); //输出二叉树副本中序遍历序列,并与源二叉树进行比较printf("
");while(1){printf(" 如果在源二叉树中查找,请输入 1;如果在二叉树副本中查找,请输入 2: ");scanf("%d",&k);if(k!=1&&k!=2){printf(" 选择错误!请重新输入! 
");fflush(stdin); //清空输入}else{printf(" 请输入要查找的节点: ");scanf("%d",&key);}if(k==1){printf(" 查找结果如下: ");r1=search(r,key);printf("
");break;}if(k==2){printf(" 查找结果如下: ");r2=search(copyr,key);printf("
");if(r2==NULL) break; //副本中不存在该数据,输出提示源二叉树是否存在else { // 副本中存在该数据,删除操作printf(" 如果要删除数据,请输入 1; 否则,请输入 0: ");scanf("%d",&m);if(m){DeleteNode(copyr,r2->data); //删除节点printf(" 删除成功! ");printf("
");printf(" 源二叉树中序遍历: ");inorder(r); //调用中序遍历函数,输出源二叉树中序遍历序列printf("
");printf(" 源二叉树的高度 :");printf("%d
",GetHeight(r)); //输出源二叉树的高度printf(" 二叉树副本中序遍历: ");inorder(copyr); // 输出二叉树副本中序遍历序列printf("
");printf(" 二叉树副本的高度 :");printf("%d
",GetHeight(r)); //输出二叉树副本的高度break; }else break;} } }free(arr); //使用完后要释放所申请的空间return 0;}


二叉树的使用

JUST DO IT!

个人笔记本

新浪微博|我的头发可没乱


以上是关于二叉树的使用的主要内容,如果未能解决你的问题,请参考以下文章

python代码计算二叉树的深度

二叉树的创建和遍历

代码随想录算法训练营第16天 | ● 104.二叉树的最大深度 559.n叉树的最大深度 ● 111.二叉树的最小深度 ● 222.完全二叉树的节点个数

LeetCode与《代码随想录》二叉树篇:做题笔记与总结-JavaScript版

二叉树的非递归遍历怎么写?

144_二叉树的前序遍历