Implementación de árbol binario (estructura de datos + lenguaje C)

1. Llamada a la función principal

a. Usamos una matriz para almacenar todos los nodos en el árbol binario, y los almacenamos en un método transversal de preorden (el árbol binario debe crearse en un método de preorden al crearlo a continuación, y el método de almacenamiento en la matriz debe ser el igual que cuando se creó) Nudos vacíos Los puntos se representan con #. En la función principal, solo necesitamos definir un puntero para almacenar el nodo raíz. De acuerdo con el nodo raíz, podemos acceder a todos los nodos en el árbol binario.

//主函数
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. Crea un árbol binario

a) El primero es el establecimiento del árbol binario, usamos el método recursivo para crear el árbol binario.

Tipo de estructura :

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

Cree un árbol binario utilizando el recorrido de preorden :

b. Echemos un vistazo a tres parámetros aquí. El primer parámetro es la matriz que almacena los nodos del árbol binario, el segundo parámetro es la longitud de la matriz y el tercer parámetro se usa para juzgar si la matriz está terminada. Use variables ordinarias para ingresar recursivamente Cuando está en la primera capa, no se puede cambiar y no se puede juzgar, por lo que pasamos la dirección de la variable para juzgar si la matriz está terminada.

//通过前序遍历创建二叉树
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. Destruye el árbol binario

1. Cuando creamos un árbol binario en la función principal, usamos una variable de puntero para almacenar el nodo raíz, por lo que solo necesitamos liberar el espacio al que apunta el puntero al destruir el árbol binario, porque en realidad operamos en el puntero. variable en la función, por lo que su dirección debe pasarse a la función, por lo que la dirección de la variable de puntero debe pasarse a la función, por lo que aquí se usa un puntero de segundo nivel.

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

4. Encuentra el número de nodos en el árbol binario

a. Utilice la recursividad para calcular el número de nodos en el árbol binario. Al atravesar un nodo vacío, devuelve 0. Si no es un nodo vacío, devuelve el número de sus nodos secundarios izquierdos más sus propios nodos secundarios derechos. Agregue su propio nodo.

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

5. Encuentra el número de nodos hoja de un árbol binario

a. Calcular el número de nodos hoja del árbol binario de forma recursiva. Al atravesar un nodo vacío, devuelve 0. Si es un nodo no vacío y sus nodos secundarios izquierdo y derecho están vacíos, prueba que el node es un nodo de hoja y devuelve 1 directamente. , si no es un nodo vacío pero no es un nodo de hoja, devuelve el número de nodos de hoja en su subárbol izquierdo más el número de nodos de hoja en su subárbol derecho.

//二叉树叶子结点个数
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. Encuentra el número de nodos en el k-ésimo nivel del árbol binario

a.Use un método recursivo para encontrar el número de nodos en la capa k-ésima del árbol binario, de modo que cuando pasemos parámetros, tengamos un parámetro adicional k, y cuando lleguemos a un nodo vacío, devuelva 0, y lo pasaremos cada vez que atravesamos a su nodo hijo. Cuando el parámetro k se reduce en uno, cuando se detecta que k es 0, significa que la k-ésima capa ha sido atravesada. En este momento, si el nodo no está vacío, lo hará devolverá directamente 1. Si el nodo no está vacío ni es la k-ésima capa, devolverá directamente el número de nodos en el nivel k en el subárbol izquierdo del nodo más el número de nodos en el nivel k en el subárbol derecho del nodo.

//二叉树第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. Encuentra el nodo cuyo valor es x en el árbol binario

a. Use el método recursivo para encontrar el nodo cuyo valor es x, y regrese vacío cuando atraviese un nodo vacío. Si no es un nodo vacío, juzgue si el valor del nodo es x, y si es x, devuelva el nodo directamente, (por lo que el algoritmo se recorre en orden previo, por lo que solo se puede encontrar el primer nodo con el valor de x), si el nodo no es un nodo vacío ni un nodo con un valor de x, directamente devuelve los nodos no vacíos en sus subárboles izquierdo y derecho.

//二叉树查找值为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. Encuentra la profundidad del árbol binario

a) Calcula recursivamente la profundidad del árbol binario, al atravesar un nodo vacío devuelve 0, si el nodo no es un nodo vacío devuelve el mayor de su subárbol izquierdo y subárbol derecho más su propio nivel.

//求二叉树的深度
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. Recorrido previo y posterior al orden del árbol binario

Recorrido de pedido anticipado del árbol binario (lenguaje C) - Se busca programador

Recorrido en orden del árbol binario (lenguaje C) - Se busca programador

Recorrido posterior al pedido del árbol binario (lenguaje C) - Se busca programador

10. Travesía de orden de nivel del árbol binario

a. Usamos una forma recursiva para atravesar el orden de niveles del árbol binario. Este algoritmo es similar a encontrar el número de elementos en el nivel k. Cuando pasamos parámetros, pasamos un parámetro i adicional para juzgar el número de niveles. Cada recorrido de los nodos secundarios de un nodo Cuando se hace clic en el punto, i se resta por uno. Cuando i es 0, la capa se puede atravesar a la capa correspondiente e imprimir directamente. Por lo tanto, primero encontramos la altura n del árbol binario, y luego use el bucle para pasar los parámetros de 0 a n para llamar a la primera función.Los datos de cada capa se pueden imprimir.

//二叉树的层序遍历
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. Determinar si un árbol binario es un árbol binario completo

a. Los nodos en el árbol binario se almacenan mediante un recorrido de orden de capas. Cuando se encuentra un nodo vacío, se almacena directamente como #. Después del almacenamiento, se recorre la matriz para calcular el número. Cuando se encuentra con #, se se detiene, y el número calculado es en este momento.Si el número de nodos es el mismo que el del árbol binario, el árbol binario devolverá 1 como un árbol binario completo (debemos saber que el árbol binario completo no encontrará un nodo vacío antes de atravesar al último nodo cuando se utiliza el orden transversal de capas. Si se encuentra, el árbol no está completo. Árbol binario), si es diferente, el árbol binario no es un árbol binario completo y devuelve 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;
}

Supongo que te gusta

Origin blog.csdn.net/weixin_49312527/article/details/122901882
Recomendado
Clasificación