1.定义二叉树的结构体
#pragma once
#include
typedef char TreeNodeType;
typedef struct TreeNode {
TreeNodeType data;
struct TreeNode* lchild; //左孩子指针
struct TreeNode* rchild; //右孩子指针
} TreeNode;
2.初始化二叉树
void TreeInit(TreeNode** root){
if(root==NULL){
return;
}
*root=NULL;
}
3.创建二叉树的节点
开辟动态内存空间来保存节点信息。
TreeNode* CreateTreeNode(TreeNodeType value){
TreeNode* new_node=(TreeNode*)malloc(sizeof(TreeNode));
new_node->data=value;
}
4.通过递归的方法来前序遍历访问二叉树
前序遍历:先访问根结点,再访问左子树,最后访问右子树
void PreOrder(TreeNode* root){
if(root==NULL){
printf("#");
return;
}
printf("%c",root->data);
PreOrder(root->lchild);
PreOrder(root->rchild);
}
5,通过递归的方法来中序遍历访问二叉树
中序遍历:先访问左子树,再访问根结点,最后访问右子树
void InOrder(TreeNode* root){
if(root==NULL){
return;
}
InOrder(root->lchild);
printf("%c ",root->data);
InOrder(root->rchild);
}
6,通过递归的方法来后续遍历二叉树
后序遍历:先访问左子树,再访问右子树,最后访问根节点
void PostOrder(TreeNode* root){
if(root==NULL){
return;
}
PostOrder(root->lchild);
PostOrder(root->rchild);
printf("%c ",root->data);
}
7.层序遍历二叉树
层序遍历思想:利用队列
void LevelOrder(TreeNode* root){
seqqueue q;
seqqueuePush(&q,root);
//2.循环的取队首元素
TreeNode* cur=NULL;
while(seqqueueTop(&q,&cur)){
//3.访问队首元素并出队列
printf("%c ",cur);
seqqueuePop(&q);
if(cur->lchild!=NULL){
seqqueuePush(&q,cur->lchild);
}
if(cur->rchild!=NULL){
seqqueuePush(&q,cur->rchild);
}
//4.将队首元素的左子树节点和右子树节点都依次入队列
//5.进入下一次循环,直到队列为空,说明遍历完了
}
}
8.通过给定的前序遍历的字符串数组来创建二叉树
前提:前序遍历的节点里若左右子树不存在则用‘#’代替
TreeNode* _TreeCreate(TreeNodeType array[],size_t size,size_t* index,TreeNodeType null_node){
if(index==NULL){
return NULL;
}
if(*index>=size){
return NULL;
}
if(array[*index]==null_node){
return NULL;
}
TreeNode* new_node=CreateTreeNode(array[*index]);
++(*index);
new_node->lchild=_TreeCreate(array,size,index,null_node);
++(*index);
new_node->rchild=_TreeCreate(array,size,index,null_node);
return new_node;
}
TreeNode* TreeCreate(TreeNodeType array[],size_t size,TreeNodeType null_node){
size_t index=0;
return _TreeCreate(array,size,&index,null_node);
}
测试代码
void TestCreateTree(){
TestHeader;
TreeNode* root;
TreeNodeType array[]="abd##e##c#f##";//前序遍历的结果
root=TreeCreate(array,strlen(array),'#');
printf("前序遍历为:");
PreOrder(root);
printf("\n");
printf("中序遍历为:");
InOrder(root);
printf("\n");
printf("后序遍历为:");
PostOrder(root);
printf("\n");
}
9.销毁二叉树
void TreeDestroy(TreeNode** root){
if(root==NULL){
return ;
}
if(*root==NULL){
return;
}
TreeNode* to_delete=*root;
TreeDestroy(&to_delete->lchild);
TreeDestroy(&to_delete->rchild);
Destroy(to_delete);
}
10.克隆二叉树
TreeNode* TreeClone(TreeNode* root){
if(root==NULL){
return NULL;
}
TreeNode* new_node=CreateTreeNode(root->data);//创建新的二叉树根结点
new_node->lchild=TreeClone(root->lchild);
new_node->rchild=TreeClone(root->rchild);
return new_node;
}
11.求一棵树中节点的个数
思想:节点的个数=根结点+根结点所有的左子树节点个数+根结点所有的右子树节点个数
size_t TreeSize(TreeNode* root){
if(root==NULL){
return 0;
}
return 1+TreeSize(root->lchild)+TreeSize(root->rchild);
}
12.求第K层节点的个数
思想:向下递归,每递归一次K-1,当K=1时即为当前要找的K层
size_t TreeKLevelSize(TreeNode* root, int k){
if(root==NULL||k<1){
return 0;
}
if(k==1){
return 1;
}
return TreeKLevelSize(root->lchild,k-1)+TreeKLevelSize(root->rchild,k-1);
}
13.求二叉树的高度
size_t TreeHeight(TreeNode* root){
if(root==NULL){
return 0;
}
size_t m=TreeHeight(root->lchild) ;
size_t n=TreeHeight(root->rchild);
return 1+(m>n?m:n);
}
14.查找节点
TreeNode* TreeFind(TreeNode* root, TreeNodeType to_find){
if(root==NULL){
return NULL;
}
if(root->data==to_find){
return root;
}
TreeFind(root->lchild,to_find);
TreeFind(root->rchild,to_find);
}
15.查找所给节点的左子树,右子树,父节点
TreeNode* LChild(TreeNode* node){
if(node==NULL){
return NULL;
}
return node->lchild;
}
TreeNode* RChild(TreeNode* node){
if(node==NULL){
return NULL;
}
return node->rchild;
}
TreeNode* Parent(TreeNode* root, TreeNode* node){
if(node==NULL||root==NULL){
return NULL;
}
if(root->lchild==node||root->rchild==node){
return root;
}
TreeNode* lret=Parent(root->lchild,node);
TreeNode* rret=Parent(root->rchild,node);
return lret!=NULL?lret:rret;
}
16.非递归前序遍历二叉树
void PreOrderByLoop(TreeNode* root){
if(root==NULL){
return;
}
seqStack stack;
seqStackInit(&stack);
seqStackPush(&stack,root);
TreeNode* cur=NULL;
while(seqStackFront(&stack,&cur)){
printf("%c ",cur);
seqStackPop(&stack);
if(cur->lchild!=NULL){
seqStackPush(&stack,cur->lchild) ;
}
if(cur->rchild){
seqStackPush(&stack,cur->rchild);
}
}
}
17.非递归中序遍历二叉树
void InOrderByLoop(TreeNode* root){
if(root==NULL){
return;
}
seqStack stack;
seqStackInit(&stack);
TreeNode* cur=root;
while(1){
while(cur!=NULL){
cur=cur->lchild;
seqStackPush(&stack,&cur);
}
TreeNode* top=NULL;
int ret=seqStackFront(&stack,&top);
if(ret==0){
return;
}
seqStackPop(&stack);
cur=top->rchild;
}
return;
}
18.非递归后序遍历二叉树
void PostOrderByLoop(TreeNode* root){
if(root==NULL){
return;
}
seqStack stack;
seqStackInit(&stack);
TreeNode* cur=root;//cur保存当前节点
TreeNode* pre=NULL;//pre保存前一个访问过的节点
while(cur!=NULL){
seqStackPush(&stack,&cur);
cur=cur->lchild;
}
TreeNode* top=NULL;
seqStackFront(&stack,&top);
if(top->rchild==NULL||top->rchild==pre){
printf("%c ",top);
seqStackPop(&stack);
pre=top;
}else{
cur=top->rchild;
}
}
19.镜像二叉树
//递归版本
void swap(TreeNode** lnode,TreeNode** rnode){
TreeNode* tmp=*lnode;
*lnode=*rnode;
*rnode=tmp;
return;
}
void TreeMirror(TreeNode* root){
if(root==NULL){
return;
}
//访问动作就是交换左右子树
swap(&root->lchild,&root->rchild);
TreeMirror(root->lchild);
TreeMirror(root->rchild);
}
//非递归版本
void TreeMirrorByLoop(TreeNode* root){
if(root==NULL){
return;
}
seqqueue q;
seqqueueInit(&q);
seqqueuePush(&q,root);
TreeNode* cur=NULL;
while(seqqueueTop(&q,&cur)){
swap(&cur->lchild,&cur->lchild);
seqqueuePop(&q);
if(cur->lchild!=NULL){
seqqueuePush(&q,cur->lchild);
}
if(cur->rchild!=NULL){
seqqueuePush(&q,cur->rchild);
}
}
return;
}
20.判断二叉树是否为完全二叉树
思想:
阶段一:任何一个节点同时具备左右子树,一旦发现某个节点不是同时具备
a>当前节点只有右子树,一定不是完全二叉树
b>如果当前节点只有左子树,进入阶段二
c>如果当前节点没有子树,也进入阶段二
阶段二:任何一个节点都必须没有子树
当遍历结束之后,所有的条件都满足,说明这个树是二叉树,否则,不是。
int IsCompleteTree(TreeNode* root){
if(root==NULL){
return 0;
}
int if_start_step_two_flag=0;
seqqueue q;
seqqueueInit(&q);
seqqueuePush(&q,root);
TreeNode* cur=NULL;
while(seqqueueFront(&q,&cur)){
seqqueuePop(&q);
if(if_start_step_two_flag==0){
if(cur->lchild!=NULL&&cur->rchild!=NULL){
seqqueuePush(&q,cur->lchild);
seqqueuePush(&q,cur->rchild);
}else if(cur->lchild==NULL&&cur->rchild!=NULL){
return 0;
}else if(cur->lchild!=NULL&&cur->rchild==NULL){
if_start_step_two_flag=1;
seqqueuePush(&q,cur->lchild);
}else{
if_start_step_two_flag=1;
}
}else{
if(cur->lchild==NULL&&cur->rchild==NULL) {
;
}else{
return 0;
}
}
}
}