Implementation of binary tree (data structure + C language)

1. Main function call

a. We use an array to store all the nodes in the binary tree, and store them in a preorder traversal method (the binary tree must be created in a preorder method when creating it below, and the storage method in the array must be the same as when it was created) Empty knots Points are represented by #. In the main function, we only need to define a pointer to store the root node. According to the root node, we can access all nodes in the binary tree.

//主函数
int main(){
  BTDataType str[]="ABD##E#H##CF##G##";
  int num=0;
  int k=0;
  char x,Empty;
  BTNode* root;
  root=CreateBinaryTree(str,strlen(str),&num);
  printf("层序遍历为:");
  BinaryTreeLevelOrder(root);
  printf("结点个数为:%d\n",BinaryTreeSize(root));
  printf("叶子结点个数为:%d\n",BinaryTreeLeafSize(root));
  printf("请输入k=");
  scanf("%d",&k);
  printf("第%d层节点的个数为:%d\n",k,BinaryTreeLevelKSize(root,k));
  Empty=getchar();
  printf("请输入x=");
  scanf("%c",&x);
  printf("以%c为根的树中总共有%d个节点\n",x,BinaryTreeSize(BinaryTreeFind(root,x)));
  printf("二叉树的深度为:%d\n",BinaryTreeDepth(root));
  printf("%d\n",BinaryTreeComplete(root));
  BinaryTreeDestory(&root);
  return 0;
}

2. Create a binary tree

a. The first is the establishment of the binary tree. We use the recursive method to create the binary tree.

Structure type :

typedef struct BinaryTreeNode{
  BTDataType _data;//数据域
  struct BinaryTreeNode* _left;//存储左孩子
  struct BinaryTreeNode* _right;//存储右孩子
}BTNode;

Create a binary tree using preorder traversal :

b. Let's take a look at three parameters here. The first parameter is the array that stores the nodes of the binary tree, the second parameter is the length of the array, and the third parameter is used to judge whether the array is finished. Use ordinary variables to enter recursively When it is in the first layer, it cannot be changed and cannot be judged, so we pass in the address of the variable to judge whether the array is finished.

//通过前序遍历创建二叉树
BTNode* CreateBinaryTree(BTDataType* str,int n,int* pi){
  if('#' == str[*pi]){//判出条件
    return NULL;
  }
  if(*pi < n){//判断数组是否走完
    BTNode* cur=(BTNode*)malloc(sizeof(BTNode));//为节点申请空间
    cur->_data=str[*pi];//赋值
    cur->_left=NULL;
    cur->_right=NULL;
    (*pi)++;
    if(*pi < n){
      cur->_left=CreateBinaryTree(str,n,pi);//创建左孩子
    }
    (*pi)++;
    if(*pi < n){
      cur->_right=CreateBinaryTree(str,n,pi);//创建右孩子
    } 
    return cur;
  }
  return NULL;
}

3. Destroy the binary tree

1. When we create a binary tree in the main function, we use a pointer variable to store the root node, so we only need to release the space pointed to by the pointer when destroying the binary tree, because we actually operate on the pointer variable in the function, so Its address needs to be passed into the function, so the address of the pointer variable needs to be passed into the function, so a second-level pointer is used here.

//二叉树的销毁
void BinaryTreeDestory(BTNode** root){
  if(NULL==*root){
    return;
  }
  free(*root);
  *root=NULL;
}

4. Find the number of nodes in the binary tree

a. Use recursion to calculate the number of nodes in the binary tree. When traversing to an empty node, it returns 0. If it is not an empty node, it returns the number of its left child nodes plus its own right child nodes. Add your own node.

//二叉树的结点个数
int BinaryTreeSize(BTNode* root){
  if(NULL==root){
    return 0;
  }
  return BinaryTreeSize(root->_left)+BinaryTreeSize(root->_right)+1;
}

5. Find the number of leaf nodes of a binary tree

a. Calculate the number of leaf nodes of the binary tree in a recursive way. When traversing to an empty node, it returns 0. If it is a non-empty node and its left and right child nodes are empty, it proves that the node is a leaf node and returns 1 directly. , if it is a non-empty node but not a leaf node, return the number of leaf nodes in its left subtree plus the number of leaf nodes in its right subtree.

//二叉树叶子结点个数
int BinaryTreeLeafSize(BTNode* root){
  if(NULL==root){
    return 0;
  }
  if(NULL==root->_left && NULL==root->_right){
    return 1;
  }
  return BinaryTreeLeafSize(root->_left)+BinaryTreeLeafSize(root->_right);
}

6. Find the number of nodes in the kth level of the binary tree

a. Use a recursive method to find the number of nodes in the kth layer of the binary tree, so when we pass parameters, we have an additional parameter k, and when we reach an empty node, it returns 0, and we pass it every time we traverse to its child node. When the parameter k is reduced by one, when it is detected that k is 0, it means that the kth layer has been traversed. At this time, if the node is not empty, it will directly return 1. If the node is neither empty nor the kth layer, it will directly return the The number of nodes at level k in the left subtree of the node plus the number of nodes at level k in the right subtree of the node.

//二叉树第k层结点的个数
int BinaryTreeLevelKSize(BTNode* root,int k){
  if(NULL==root){
    return 0;
  }
  if(0==k){
    return 1;
  }
  return BinaryTreeLevelKSize(root->_left,k-1)+BinaryTreeLevelKSize(root->_right,k-1);
} 

7. Find the node whose value is x in the binary tree

a. Use recursive method to find the node whose value is x, and return empty when traversing an empty node. If it is not an empty node, judge whether the value of the node is x, and if it is x, return the node directly, (so the algorithm is It is traversed in a preorder manner, so only the first node with the value of x can be found), if the node is neither an empty node nor a node with a value of x, it will directly return the non-empty nodes in its left and right subtrees. Node.

//二叉树查找值为x的节点
BTNode* BinaryTreeFind(BTNode* root,BTDataType x){
  if(NULL==root){
    return NULL;
  }
  if(x==root->_data){
    return root;
  }
  BTNode* first=BinaryTreeFind(root->_left,x);
  BTNode* second=BinaryTreeFind(root->_right,x);
  if(NULL==first){
    return second; 
  }
  return first;
}

8. Find the depth of the binary tree

a. Calculate the depth of the binary tree recursively. When traversing to an empty node, it returns 0. If the node is not an empty node, it returns the larger one of its left subtree and right subtree plus its own level.

//求二叉树的深度
int BinaryTreeDepth(BTNode* root){
  if(NULL==root){
    return 0;
  }
  int Dep_1=BinaryTreeDepth(root->_left);
  int Dep_2=BinaryTreeDepth(root->_right);
  if(Dep_1>Dep_2){
    return Dep_1+1;
  }
  return Dep_2+1;
}

9. Pre-, post-order traversal of binary tree

Preorder traversal of binary tree (C language) - Programmer Sought

In-order traversal of binary tree (C language) - Programmer Sought

Post-order traversal of binary tree (C language) - Programmer Sought

10. Level order traversal of binary tree

a. We use a recursive way to traverse the level order of the binary tree. This algorithm is similar to finding the number of elements in the kth level. When we pass parameters, we pass an additional parameter i to judge the number of levels. Each traversal of a node's child nodes When the point is clicked, i is subtracted by one. When i is 0, the layer can be traversed to the corresponding layer and printed directly. Therefore, we first find the height n of the binary tree, and then use the loop to pass the parameters from 0 to n to call the first function. The data of each layer can be printed.

//二叉树的层序遍历
void BinaryTreeLevelOrder_1(BTNode* root,int i){
  if(NULL==root){
    return;
  }
  if(0==i){
    printf("%c",root->_data);
    return;
  }
  BinaryTreeLevelOrder_1(root->_left,i-1);
  BinaryTreeLevelOrder_1(root->_right,i-1);
}

void BinaryTreeLevelOrder(BTNode* root){
  if(NULL==root){
    return;
  }
  int Dep_=BinaryTreeDepth(root);
  int i;
  for(i=0;i<Dep_;i++){
    BinaryTreeLevelOrder_1(root,i);
  }
  printf("\n");
}

11. Determine whether a binary tree is a complete binary tree

a. The nodes in the binary tree are stored by means of layer-order traversal. When an empty node is encountered, it is directly stored as #. After storage, the array is traversed to calculate the number. When it encounters #, it stops, and the calculated number is at this time. If the number of nodes is the same as that of the binary tree, the binary tree will return 1 as a complete binary tree (we should know that the complete binary tree will not encounter an empty node before traversing to the last node when using layer order traversal. If it is encountered, the tree is not complete. Binary tree), if different, the binary tree is not a complete binary tree and returns 0.

//判断二叉树是否是完全二叉树
void BinaryTreeComplete_1(BTNode* root,int i,BTDataType* arry,int* num){
  if(NULL==root){
    arry[(*num)++]='#';
    return;
  }
  if(0==i){
    arry[(*num)++]=root->_data;
    return;
  }
  BinaryTreeComplete_1(root->_left,i-1,arry,num);
  BinaryTreeComplete_1(root->_right,i-1,arry,num);
}

int BinaryTreeComplete(BTNode* root){
  if(NULL==root){
    printf("该节点为空!\n");
    return -1;
  }
  BTDataType* arry=(BTDataType*)malloc(sizeof(BTDataType)*2*BinaryTreeSize(root));
  if(NULL==arry){
    printf("申请失败!\n");
    return -1;
  }
  int i=0;
  int count=0;
  int num=0;
  for(i=0;i<BinaryTreeDepth(root);i++){
    BinaryTreeComplete_1(root,i,arry,&num);
  }
  while(arry[count] != '#'){
    count++;
  }
  if(BinaryTreeSize(root)==count){
    return 1;
  }
  return 0;
}

Guess you like

Origin blog.csdn.net/weixin_49312527/article/details/122901882