当前位置: 首页 > 知识库问答 >
问题:

扁平化二分搜索到有序单链表[C]

范朗
2023-03-14

我正在尝试将二叉查找树展平为单链表。

二进制搜索树:

      6
    /   \
   4     8
  / \     \
 1  5     11
         / 
       10

扁平化单边链表:

1 -> 4 -> 5 -> 6 -> 8 -> 10 -> 11

我似乎不知道为什么。

我有一个树节点的结构:

typedef stuct node {
    int key;
    struct node *left;
    struct node *right;
} Node;

我有一个创建和分配内存到树节点的功能:

Node* newNode (int key) {
    Node *new = malloc (sizeof(Node));
    new->left = NULL;
    new->right = NULL;
    new->key = key;
    return new;
}

我有一个列表节点的结构:

typedef struct list {
    int key;
    struct list* next;
} List;

我有一个创建列表节点的函数:

List* newListNode (int key) {
    List *new = malloc(sizeof(List));
    new->key = key;
    new->next = NULL;
    return new;
}

我有工作函数来创建二叉搜索树,插入值,等等,但现在我需要创建一个函数来将树展平为列表。

List* flattenToLL(Node* root) {
    ...
}

我只是想不出如何将它展平到一个单链表。我见过很多其他的帖子和网站讨论将二叉搜索树转换为双链表或循环链表,但没有一个讨论将值复制到单链表中。如果有人能就我如何做到这一点提出建议,我将不胜感激。这是一个家庭作业,所以如果你也能提供一个小的解释,帮助我学习,这将是伟大的。

共有3个答案

耿星雨
2023-03-14
Why dont you do inorder traversal and add values to list in a way.  

public List<Integer> inorderToList(TreeNode<Integer> node, List<Integer> list) {
        if(node == null) {
            return list;
        } 
        if (node != null) {
            list = inorderToList(node.getLeft(), list);
            list.add(node.getValue());
            list = inorderToList(node.getRight(), list);
        }
        return list;
    }
华子昂
2023-03-14

您需要按顺序遍历,将每个元素依次添加到列表中。

这方面的伪代码是:

def traverse (node, list):
    if node == NULL: return       # Ignore empty subtrees.
    traverse (node.left, list)    # Do left subtree first.
    list.append (node.data)       # Then current node.
    traverse (node.right, list)   # Then right subtree.

list = new List()                 # Create empty list.
traverse (root, list)             # Collapse tree to list.

就这样,尽可能简单。第1步,处理左侧子树。第2步,添加数据。第3步,处理右侧子树。

唯一“聪明”的地方是以一种简洁的方式正确处理空子树。

请记住,为了获得最大效率,如果指向最终元素(tail)的指针没有缓存在某个地方,那么将其附加到链表可能是一个相对昂贵的操作。这将需要为添加的每个元素找到尾部,这将把你的展平算法变成一个O(n21。

由于在链表的开头插入一个元素几乎总是O(1),因为您必须维护一个head指针,所以通常更有效的方法是反向遍历:

def traverse (node, list):
    if node == NULL: return       # Ignore empty subtrees.
    traverse (node.right, list)   # Do right subtree first.
    list.insert (node.data)       # Then current node at list start.
    traverse (node.left, list)    # Then left subtree.

这将扁平化操作保持在O(n)

白智
2023-03-14

这是相对简单的递归操作:

  • 检查左侧的节点;如果有什么,请将左侧展平为列表#1

以下是如何编写代码:

List* flattenToLL(Node* root) {
    List *list1 = (root->left) ? flattenToLL(root->left) : NULL;
    List *list2 = (root->right) ? flattenToLL(root->right) : NULL;
    List *list3 = newNode(root->key);
    // The "middle" list3 cannot be NULL; append list2 to list3
    list3->next = list2; // If list2 is NULL, it's OK
    if (!list1) return list3; // Nothing to prepend
    List *last = list1;
    while (last->next) last=last->next; // Go to the end of list1
    last->next = list3; // Append list3+list2 to the end of list1
    return list1;
}
 类似资料:
  • 我正在研究一种递归算法,将二叉树扁平化为单链表。问题陈述: 我写了下面的递归代码,它根本不起作用(返回错误的答案),但我不能从概念上理解为什么不起作用。从根开始,我们拉平根。左根和右根。如果root.left存在,那么root.next(在本例中是root.right)将指向扁平化的left列表。然后,左列表指向右列表的开始。这将沿着树递归地继续下去。 这在概念上有问题吗?我尝试在预序遍历之后对它

  • 本文向大家介绍Python分组扁平化列表,包括了Python分组扁平化列表的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将编写一个程序,将包含子列表的列表展开。给定的数字将子列表展开,直到给定的数字索引作为部分。让我们看一个例子来清楚地理解它。 输入项 输出结果 让我们看看解决问题的步骤。 初始化列表和编号。 初始化一个空列表。 使用范围(0,len(lists),number遍历列表

  • 是什么导致了错误? 下面是我的代码:

  • 代码是一个简单的二分搜索程序。我试着追踪程序,但它只会让我更加困惑。我不明白为什么嵌套的if has data,min,midpoint-1,&target和底部的else if语句has data,midpoint+1,max,target。

  • 在我的解决方案中,我遇到了一个“None's not have.val”的问题。。。我想知道如何调试它。。。 以下是描述 将BST转换为已排序的循环双链接列表。将左指针和右指针视为双链接列表中上一个和下一个指针的同义词。] 让我们以下面的BST为例,它可能会帮助您更好地理解这个问题:我们希望将这个BST转换为一个循环双链接列表。双链表中的每个节点都有一个前导节点和后继节点。对于循环双链表,第一个元

  • 问题内容: 我有一个这样的清单: 此列表中的每个项目可能包含一个数据对或一个元组,我想将此列表更改为 然后这样做: 我不知道如何更改列表结构,或者如何基于原始列表进行相同的计算? 问题答案: 如果您只想整理列表,请使用:http : //docs.python.org/library/itertools.html#itertools.chain.from_iterable