我正在尝试实现一个levelOrder函数,它接受树的指针并逐级打印树的数据。这是《C如何编程》一书中的一个问题,完整问题如下:
(级序二叉树遍历)Fig的程序。12.19说明了遍历二叉树的三种递归方法——顺序遍历、前序遍历和后序遍历。此练习演示了二叉树的级别顺序遍历,其中节点值从根节点级别开始逐级打印。每个级别上的节点从左到右打印。级序遍历不是递归算法。它使用队列数据结构来控制节点的输出。算法如下:
>
在队列中插入根节点
虽然队列中还有节点,
获取队列中的下一个节点
打印节点的值
如果指向节点左子节点的指针不为NULL,请在队列中插入左子节点
如果指向节点的右子节点的指针不为NULL,请在队列中插入右子节点。
写入函数levelOrder以执行二叉树的级别顺序遍历。该函数应将指向二叉树根节点的指针作为参数。修改图12.19的程序以使用此功能。将此函数的输出与其他遍历算法的输出进行比较,以确定其工作是否正确。[注:您还需要在本程序中修改和合并图12.13中的队列处理功能。]
我的尝试如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct treeNode{
struct treeNode* left;
int data;
struct treeNode* right;
};
struct queueNode{
struct treeNode* tree;
struct queueNode* next;
};
/* prototype */
void insert(struct treeNode**, int); // tree creator
void levelOrder(struct treeNode**);
void inOrder(struct treeNode*);
void enqueue(struct queueNode**, struct queueNode**, struct treeNode*);
struct treeNode* dequeue(struct queueNode**, struct queueNode**);
int main(){
struct treeNode* root = NULL;
levelOrder(&root);
}
void insert(struct treeNode** root, int val){
if(!(*root)){ // when root is empty
*root = (struct treeNode*)malloc(sizeof(struct treeNode));
if(*root){ // if allocation is achieved
(*root) -> data = val;
(*root) -> right = NULL;
(*root) -> left = NULL;
} else { // if allocation is not succesfull
printf("%s\n", "[ERROR] Not enough memory space for allocation!");
}
} else { // if root is not empty
if(val > (*root) -> data)
insert(&(*root) -> right, val);
else if(val < (*root) -> data)
insert(&(*root) -> left, val);
}
}
void enqueue(struct queueNode** head, struct queueNode** tail, struct treeNode* tree){
struct queueNode* newNode = (struct queueNode*)malloc(sizeof(struct queueNode));
if( newNode ){
newNode -> tree = tree;
newNode -> next = NULL;
if(!(*head)){
*head = newNode;
//printf("head->tree->data:%d --> ", (*head)->tree->data);
printf("%d --> ", (*head)->tree->data);
}
else{
(*tail) -> next = newNode;
//printf("tail->tree->data:%d --> ", (*tail)->tree->data);
printf("%d --> ", (*tail)->tree->data);
}
(*tail) = newNode;
} else {
printf("%s\n", "[ERROR] Not enough memory space for allocation!");
}
}
struct treeNode* dequeue(struct queueNode** head, struct queueNode** tail){
struct treeNode* val = (*head)->tree;
struct queueNode* temp = *head;
*head = (*head) -> next;
if(!(*head))
*tail = NULL;
return val;
}
void levelOrder(struct treeNode** root){
struct treeNode* output = NULL;
struct queueNode* head = NULL, *tail = NULL;
size_t i;
srand(time(NULL));
for(i = 0; i < 9; ++i){
insert(root, 1 + rand()%16);
}
puts("in order");
inOrder(*root);
puts("NULL");
puts("After in order");
enqueue(&head, &tail, *root);
while(head){
if(head->tree->left)
enqueue(&head, &tail, head->tree->left);
if(head->tree->right)
enqueue(&head, &tail, head->tree->right);
head = head->next;
}
/*for(i=0;i<9;++i){
output = dequeue(&head, &tail);
printf("%d",output->data);
}*/
}
void inOrder(struct treeNode* tree){ // used to be sure if my implementation works correct
if(tree != NULL){
inOrder(tree->left);
printf("%-2d-->", tree->data);
inOrder(tree->right);
}
}
当我使用退出函数时,它不能正常工作。我不能得到队列中的所有树与队列函数。但是,如果我打印队列中的值,它会打印所有添加的值,除了一个(我不打印哪个),但会打印第一个值两次。(你能运行代码吗?我想把输出放在这里,但stackoverflow认为它是一个代码块,我不能编辑它,所以它不让我添加它。(
一些问题:
>
在enqueue
中的else
块中,在移动tail
之前打印该值:这可能会误导输出的读取器,因为该值不是附加到队列中的值。我假设这是为了调试,但最后不应该在这里打印。
在主循环中,您不应该像那样移动head
引用。取而代之的是在循环开始时使用de队列
,并捕获您已经声明的输出
变量中的节点,并立即打印相应的值。这将保持队列的大小不超过必要的长度。
while(head){
output = dequeue(&head, &tail); // extract
printf("%d --> ", output->data); // print here instead of in enqueue
if(output->left) // use output
enqueue(&head, &tail, output->left);
if(output->right)
enqueue(&head, &tail, output->right);
// Don't move head here
}
puts("\n");
在dequeue
中,您应该在return
之前释放从队列中删除的队列节点:
free(temp);
其他一些评论:
>
evelOrder
不应该真正负责构建树。在主驱动程序代码中执行此操作,或者--如果您真的想要--在单独的函数中执行此操作。然后将第二个参数设为evelOrder
,只需struct treeNode*
,而不是struct treeNode**
。
对于调试,您的inOrder
实现将值打印在单独的行上,并使用对应于递归深度的缩进,对此您可以传递一个额外的int深度
参数。这样你就可以看到实际的树结构。
Leetcode问题:https://leetcode.com/problems/binary-tree-level-order-traversal/ 我有两个队列,我清空第一个队列(q),同时向第二个队列(q2)添加元素,这样我可以得到级别。当第一个队列为空时,我将其传递给函数以创建该级别的ArrayList并将其添加到结果值中,如果q2为空,则意味着没有添加任何内容,因此我们可以中断循环并返回
我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。
我必须创建两个类:NonBinaryTree和SingleNode类,包含一些处理节点和整个树的方法(在NonBinaryTree类中)。我在使用队列(先进先出类型)实现非二叉树的BFS(层次顺序)遍历时遇到过问题。由于二叉树有很多资源,每个节点最多有两个子节点,我还没有找到任何可以帮助我解决非二叉树问题的资源。 到目前为止,我做了这个代码: 我的树: 在此处输入图像描述 我需要按以下顺序处理节点
这是一个leetcode问题。 给定一个二叉树,返回其节点值的级序遍历(即从左到右,逐级)。 例如:给定二叉树, 将其级别顺序遍历返回为: 但我正在用JavaScript尝试一种新的方式,而不是完全按照他们的解决方案。到目前为止,我能够打印阵列,但 如何在新行中打印不同的级别 以下是我目前的代码: 输入:[3,9,20,空,空,15,7], LeetCode问题链接:BinarytreeTrave
为了上课,我必须创建一个状态对象的二叉树,每个状态对象包括一个居民对象的二叉树,这些居民对象组织住在每个州的人。我试图在一个给定的州中搜索最老的居民;然而,居民是按字母顺序组织在树中的,这对我的搜索毫无帮助。因此,我必须遍历整个居民树,更新保存最老的人的节点,并在树被完全遍历后返回它。我已经有了代码的第一部分,但是还停留在如何写递归的剩余部分。 状态树的方法: 然后是公共“包装器”状态树方法:
中序遍历二叉树 按完全二叉树的层次遍历给出一棵二叉树的遍历序列(其中用0表示虚结点),要求输出该二叉树的深度及中序遍历该二叉树得到的序列。 输入格式: 首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(n≤1000),代表给出的二叉树的结点总数(当然,其中可能包含虚结点)。结点编号均为正整数,且各不相同。 然后输入n个正整数,表示按完全二叉树(即第1层1