我正在努力实现以下功能:

给定一个二叉搜索树,返回最小的 node ,然后将指针移动到树中下一个最小的 node .在再次调用该函数时,它应该返回下一个最小的 node ,依此类推.

任何帮助都将不胜感激.

这是我到目前为止的程序,其中包含一些辅助函数及其定义:

#include <stdio.h>
#include <stdlib.h>
 
/* A binary tree node has data,
   the pointer to left child
   and a pointer to right child */
struct node {
    int data;
    struct node *left;
    struct node *right;
    struct node *parent;
};
 
struct node *minValue(struct node *node);
 
struct node *inOrderSuccessor(
    struct node *root,
    struct node *n)
{
    if (n->right != NULL)
        return minValue(n->right);
   
    struct node *p = n->parent;
    while (p != NULL && n == p->right) {
        n = p;
        p = p->parent;
    }
    return p;
}
 
/* Given a non-empty binary search tree,
    return the minimum data 
    value found in that tree. Note that
    the entire tree does not need
    to be searched. */
struct node *minValue(struct node *node)
{
    struct node *current = node;
 
    /* loop down to find the leftmost leaf */
    while (current->left != NULL) {
        current = current->left;
    }
    return current;
}
 
/* Helper function that allocates a new
    node with the given data and
    NULL left and right pointers. */
struct node *newNode(int data)
{
    struct node *node = (struct node *)malloc(sizeof(struct node));
    node->data = data;
    node->left = NULL;
    node->right = NULL;
    node->parent = NULL;
 
    return (node);
}
 
/* Give a binary search tree and
   a number, inserts a new node with   
    the given number in the correct
    place in the tree. Returns the new
    root pointer which the caller should
    then use (the standard trick to
    avoid using reference parameters). */
struct node *insert(struct node *node,
                    int data)
{
    /* 1. If the tree is empty, return a new,
      single node */
    if (node == NULL)
        return (newNode(data));
    else {
        struct node *temp;
 
        /* 2. Otherwise, recur down the tree */
        if (data <= node->data) {
            temp = insert(node->left, data);
            node->left = temp;
            temp->parent = node;
        } else {
            temp = insert(node->right, data);
            node->right = temp;
            temp->parent = node;
        }
 
        /* return the (unchanged) node pointer */
        return node;
    }
}

推荐答案

给定一个二叉搜索树,返回最小的 node ,然后将指针移动到树中下一个最小的 node .在再次调用该函数时,它应该返回下一个最小的 node ,依此类推.

struct node *next_smallest_node(struct node *root, struct node *min)
{
    if (!min)
        return min_node(root);
    
    if (min->right)
        return min_node(min->right);
   
    for (struct node *p = min->parent; p; p = min->parent) {
        // Coming from left: return parent
        if (min != p->right)
            return p;
        
        // Coming from right: stop at root
        if (p == root)
            return NULL;
        
        min = p;
    }
    
    return NULL;
}

min_node()返回树中最小的 node :

struct node *min_node(struct node *root)
{
    struct node *min = NULL;
    for (struct node *i = root; i; i = i->left) 
        min = i;
    
    return min;
}

用法:

int main(void)
{
    struct node *tree = NULL;
    // Fill tree with data ...
    
    struct node *min = NULL;
    while (min = next_smallest_node(tree, min)) {
        printf("Next smallest = %d\n", min->data);
    }
}

更新:

  • next_smallest_node()中的代码现在解析左子树(多亏了@chqrlie).
  • 在调用函数之前,不需要计算最小值.

C++相关问答推荐

当我try 计算一个多项时,看到segfault.我做错了什么?

与unions 的未定义行为

是否有任何情况(特定类型/值),类型双关在所有符合标准的C实现中产生相同的行为?

来自stdarg.h的c中的va_args无法正常工作<>

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

为什么在C中进行大量的位移位?

识别和处理c中整数溢出的最佳方法?

我在这里正确地解释了C操作顺序吗?

I2C外设在单次交易后出现故障

将变量或参数打包到 struct /联合中是否会带来意想不到的性能损失?

错误:字符串在C中获得意外输出

正在try 理解C++中的`正在释放的指针未被分配‘错误

是否有单独的缓冲区用于读写库调用?

挥发性语义的形式化理解

解密Chrome加密密钥

";错误:寄存器的使用无效;当使用-masm=intel;在gcc中,但在AT&;T模式

为什么<到达*时不会转换为>?

使用替代日历打印日期

如何向 execl 创建的后台程序提供输入?

如何正确探测平台设备?