9-二叉树简单实现
笔记
树
多叉树转换成二叉树:左孩子右兄弟
从根节点、左下方开始,节点左侧放自己左侧的孩子,右侧放自己右侧的兄弟。
二叉树
满二叉树
一颗深度为k且有(2的k次方减1)个节点
完全二叉树
除最后一层外,每一层上的节点数均达到最大值;在最后一层只缺少右边的若干节点。
示意图
遍历
先序遍历:根 左 右(遍历顺序)
中序遍历:左 根 右
后序遍历:左 右 根
要实现的接口
遍历、叶子的数量、树的高度(层数)、拷贝
在接口实现时,一般使用递归来遍历树。
二叉树中每个节点都有左孩子节点和右孩子节点(可能为NULL),函数的参数是一个节点的指针,函数内将参数做根节点使用,函数内调用递归时,传入自身的孩子节点,则相当于下一层的调用会将自身的孩子节点当作根节点,层层递归。从宏观上,就是树一层一层的遍历。
代码
start0.c
#include<stdio.h>
#include<stdlib.h>
//树的节点
struct myBinaryTree{
char ch; //数据域
struct myBinaryTree* lChild;
struct myBinaryTree* rChild;
};
//遍历打印
//利用递归,先序遍历:根 左 右
void foreachPrint(struct myBinaryTree* b){
if(NULL == b){
return;
}
//这三条语句的顺序,决定了树的遍历顺序
//这里的遍历顺序是根、左、右
printf("%c ",b->ch); //打印,可以换成其他的处理函数
foreachPrint(b->lChild);
foreachPrint(b->rChild);
}
//叶子数量
//左右都为null的节点称为叶子
void getLeaf(struct myBinaryTree* b,int* nums){
if(NULL == b){
return;
}
if(NULL==b->lChild && NULL==b->rChild){
(*nums)++;
}
getLeaf(b->lChild, nums);
getLeaf(b->rChild, nums);
}
//树的高度(层数)
int getHeight(struct myBinaryTree* b){
if(NULL == b){
return 0;
}
int lheight = getHeight(b->lChild);
int rheight = getHeight(b->rChild);
return lheight>rheight ? lheight+1 : rheight+1;
}
//拷贝树(但是作用域还是之前数据的)
struct myBinaryTree* copyBinaryTree(struct myBinaryTree* b){
if(NULL == b){
return NULL;
}
struct myBinaryTree* lChild = copyBinaryTree(b->lChild);
struct myBinaryTree* rChild = copyBinaryTree(b->rChild);
struct myBinaryTree* newNode = malloc(sizeof(struct myBinaryTree));
newNode->lChild = lChild;
newNode->rChild = rChild;
newNode->ch = b->ch;
return newNode;
}
//释放树
void freeBinaryTree(struct myBinaryTree* b){
if(NULL == b){
return;
}
freeBinaryTree(b->lChild);
freeBinaryTree(b->rChild);
free(b);
}
int main(){
struct myBinaryTree* newBt = NULL;
struct myBinaryTree bt1 = {'A',NULL,NULL};
struct myBinaryTree bt2 = {'B',NULL,NULL};
struct myBinaryTree bt3 = {'C',NULL,NULL};
struct myBinaryTree bt4 = {'D',NULL,NULL};
struct myBinaryTree bt5 = {'E',NULL,NULL};
struct myBinaryTree bt6 = {'F',NULL,NULL};
struct myBinaryTree bt7 = {'G',NULL,NULL};
struct myBinaryTree bt8 = {'H',NULL,NULL};
//按照顺序将节点连接起来
bt1.lChild = &bt2;
bt1.rChild = &bt6;
bt2.rChild = &bt3;
bt3.lChild = &bt4;
bt3.rChild = &bt5;
bt6.rChild = &bt7;
bt7.lChild = &bt8;
foreachPrint(&bt1);
printf("\n");
int leafnums = 0;
getLeaf(&bt1, &leafnums);
printf("leaf nums=%d\n",leafnums);
printf("tree height=%d\n",getHeight(&bt1));
newBt = copyBinaryTree(&bt1);
printf("-----------------\n");
foreachPrint(newBt);
printf("\n");
leafnums = 0;
getLeaf(newBt, &leafnums);
printf("leaf nums=%d\n",leafnums);
printf("tree height=%d\n",getHeight(newBt));
return 0;
}