二叉树的层次遍历的应用

判定一颗二叉树是否为完全二叉树:

int JudgeComplete(BitTree *bt)  //判断二叉树是否是完全二叉树,如是,返回1,否则,返回0

【算法思想:判定是否是完全二叉树,可以使用队列,在遍历中利用完全二叉树“某节点没有左孩子,则一定无右孩子;若某节点缺左或右孩子,则其所有后继一定无孩子”的原则进行判断。(备注:判断时易犯的错误是证明其左子树和右子数都是完全二叉树,由此推出整棵二叉树必是完全二叉树的错误结论。)】

#include<stdio.h>
#include<malloc.h>
#define MaxSize  100
typedef  char ElementType;

typedef struct Node {
    ElementType data;               /* 数据域 */
    struct Node *lchild, *rchild; /* 左、右指针域,分别存储左、右孩子的存储位置 */
} BinaryTree;

/* 先序建立二叉树 */
BinaryTree *CreBiTree( ) {
    BinaryTree *bt;
    ElementType x;
    scanf("%c", &x);
    if (x == '#') {
        bt = NULL;
    } else {
        bt = (BinaryTree *)malloc(sizeof(BinaryTree));
        bt->data = x;
        bt->lchild = CreBiTree();
        bt->rchild = CreBiTree();
    }
    return bt;
}

typedef  struct  {
    BinaryTree*  data[MaxSize];
    int  rear;
    int  front;
} CirQueue;

/*顺序循环队列初始化*/
CirQueue * CreateQueue() {
    CirQueue *q;
    q = (CirQueue*) malloc( sizeof(CirQueue ));
    q->front = 0;
    q->rear = 0;
    return q;
}

/*顺序循环队列判空,返回1表示空,0表示非空*/
int QueueEmpty(CirQueue *q) {
    if (q->front == q->rear)
        return 1;
    else
        return 0;
}

/*顺序循环队列判满,返回1表示满,0表示非满*/
int QueueFull(CirQueue *q) {
    if (q->front == (q->rear + 1) % MaxSize)
        return 1;
    else
        return 0;
}

/*顺序循环队列入队*/
void EnQueue(CirQueue *q, BinaryTree* x) {
    if (QueueFull(q)) {
        printf("overflow!");
        return;
    }
    q->data[q->rear] = x;
    q->rear =  (q->rear + 1) % MaxSize;
}

/*顺序循环队列出队*/
BinaryTree* DeQueue(CirQueue *q) {
    BinaryTree* x;
    if (QueueEmpty(q)) {
        printf("underflow!");
        return NULL;
    }
    x = q->data[q->front];
    q->front =  (q->front + 1) % MaxSize;
    return x;
}

//判断二叉树是否是完全二叉树,如是,返回1,否则,返回0
int JudgeComplete(BinaryTree *bt) {
    CirQueue *q = CreateQueue();
    BinaryTree *p;
    if (!bt) {
        return 1;    // 空树为满二叉树
    }
    EnQueue(q, bt);
    while (!QueueEmpty(q)) {
        p = DeQueue(q);
        if (p) {    // 结点非空,将其左右子树入队
            EnQueue(q, p->lchild);
            EnQueue(q, p->rchild);
        } else {    // 结点为空,检查其后是否有非空结点
            while (!QueueEmpty(q)) {
                p = DeQueue(q);
                if (p) {    // 结点非空,则二叉树为非完全二叉树
                    return 0;
                }
            }
        }
    }
    return 1;
}
/*
          A                A
       /   \          /   \
      B     C         B     C
     / \   /        /     /
    D   E F           D        E
*/
void main() {
    // ABD##E##CF### ABD###CE###
    BinaryTree *bt;
    printf("input data:");
    bt = CreBiTree();
    if (JudgeComplete(bt)) {
        printf("是完全二叉树");
    } else {
        printf("不是完全二叉树");
    }

}

  • 17
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 C 语言中,可以使用递归的方式来对二叉树进行层次遍历。 首先,需要定义一个二叉树的结构体: ``` struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; ``` 然后,可以定义一个递归函数,用于遍历二叉树的每一层: ``` void traverseLevel(struct TreeNode *root, int level) { if (root == NULL) { return; } if (level == 1) { // 在这里处理当前节点的值 } else { // 递归遍历左子树和右子树 traverseLevel(root->left, level - 1); traverseLevel(root->right, level - 1); } } ``` 最后,可以调用这个函数,按层次遍历整棵二叉树: ``` void traverse(struct TreeNode *root) { int height = getTreeHeight(root); for (int i = 1; i <= height; i++) { traverseLevel(root, i); } } ``` 其中,getTreeHeight 函数用于计算二叉树的高度,可以使用递归的方式来实现。 示例代码如下: ``` #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; int getTreeHeight(struct TreeNode *root) { if (root == NULL) { return 0; } int leftHeight = getTreeHeight(root->left); int rightHeight = getTreeHeight(root->right); return (leftHeight > rightHeight ? leftHeight : rightHeight) + 1; } void traverseLevel(struct TreeNode *root, int level) { if (root == NULL) { return; } if (level == 1) { printf("%d ", root->val); } else { traverseLevel(root->left, level - 1); traverseLevel(root->right, level - 1); } } void traverse(struct TreeNode *root) { int height = getTreeHeight(root); for (int i = 1 ### 回答2: 使用递归方式实现二叉树层次遍历较为困难,一般情况下需要借助队列来进行辅助。因为二叉树层次遍历需要按照顺序来遍历每一层的节点。 递归的思想是通过逐层递归地遍历树的节点,但是这种方式无法保证按层次遍历。 如果要求使用递归而不使用队列,可以使用递归来遍历每一层的节点,并将每一层的节点值存放在一个二维数组中。 具体实现如下: ```c #include <stdio.h> #include <stdlib.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void getHeight(struct TreeNode* root, int *max_height) { if (root == NULL) return; getHeight(root->left, max_height); getHeight(root->right, max_height); (*max_height)++; // 计算树的高度 } // 递归函数,将节点值按照层次存放在二维数组中 void levelOrder(struct TreeNode* root, int **result, int level) { if (root == NULL) return; result[level-1] = (int*)realloc(result[level-1], (level * sizeof(int))); // 分配内存 result[level-1][level-1] = root->val; // 存放节点值 levelOrder(root->left, result, level+1); // 递归遍历每一层的左子树节点 levelOrder(root->right, result, level+1); // 递归遍历每一层的右子树节点 } int** levelOrderTraversal(struct TreeNode* root, int* returnSize, int** returnColumnSizes) { int max_height = 0; getHeight(root, &max_height); // 计算二叉树的高度 int **result = (int**)malloc(max_height * sizeof(int*)); // 二维数组,存放树的节点值 *returnSize = max_height; // 返回的行数为树的高度 for (int i = 0; i < max_height; i++) { result[i] = NULL; // 初始化二维数组,置为NULL } levelOrder(root, result, 1); // 递归遍历二叉树的每一层节点 *returnColumnSizes = (int*)malloc(max_height * sizeof(int)); // 一维数组,存放每一层的列数 for (int i = 0; i < max_height; i++) { (*returnColumnSizes)[i] = i+1; // 每一层的列数为i+1 } return result; } ``` 这种方法虽然使用了递归,但是需要动态分配内存,内存的分配和释放需要注意。而且每次遍历时都需要判断节点的高度,效率较低。所以在实际应用中,使用队列来实现二叉树层次遍历更为常见和高效。 ### 回答3: 要使用C语言实现二叉树层次遍历,可以使用递归的方式来实现。通常情况下,二叉树层次遍历需要借助队列来进行操作,但是在此要求不使用队列的情况下,可以使用递归的方式来进行。 首先,我们需要确定遍历的顺序,层次遍历是从上到下,从左到右的顺序。所以我们可以定义一个函数`levelTraversal`来进行层次遍历。函数的参数包括二叉树的根节点指针和当前层的层数。 在函数内部,我们首先判断根节点是否为空,若为空则直接返回。然后,我们判断当前层是否为1,如果是1层则输出当前节点的值。接下来,我们对当前节点的左子树调用`levelTraversal`函数,将层数参数加1,并对右子树也进行同样的操作。 这样就实现了递归的层次遍历,具体代码如下: ``` #include <stdio.h> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void levelTraversal(struct TreeNode* root, int level) { if (root == NULL) { return; } if (level == 1) { printf("%d ", root->val); } levelTraversal(root->left, level - 1); levelTraversal(root->right, level - 1); } int getBinaryTreeHeight(struct TreeNode* root) { if (root == NULL) { return 0; } else { int left_height = getBinaryTreeHeight(root->left); int right_height = getBinaryTreeHeight(root->right); return (left_height > right_height) ? (left_height + 1) : (right_height + 1); } } void levelOrder(struct TreeNode* root) { int height = getBinaryTreeHeight(root); for (int i = 1; i <= height; i++) { levelTraversal(root, i); } printf("\n") } ``` 在这段代码中,我们定义了一个辅助函数`getBinaryTreeHeight`来获取二叉树的高度。然后,我们在`levelOrder`函数中进行层次遍历。遍历的范围是从第1层到二叉树的高度,对每一层都调用`levelTraversal`函数进行遍历。 注意,在实际使用中,我们需要根据自己的需求来处理节点的值,例如输出、存储等等。以上为一个简单的实现,希望对你有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值