C 二叉树-寻找K个最小元素

C 二叉树-寻找K个最小元素,c,C,你知道怎么做吗?循序渐进地 void print_lowest(Tree* root, compare_func compare, print_func print) { int k, i; int min, repeat; printf("\nEnter number of k: "); if (scanf("%d", &k) == 1); min = root->key; for (i = 0; i < k; i++) {

你知道怎么做吗?循序渐进地

void print_lowest(Tree* root, compare_func compare, print_func print) {
    int k, i; int min, repeat;
    printf("\nEnter number of k: ");
    if (scanf("%d", &k) == 1);
    min = root->key;
    for (i = 0; i < k; i++) {
        repeat = root->key;//reset value
        find_min(root, &min, repeat, compare);
        print(min);
    }
}

void find_min(Tree* root, int* min, int repeat, compare_func compare) {

    if (root != NULL) {
        find_min(root->left, min, repeat, compare);
        if (compare(root->key, repeat)==1) {//if rootkey<repeat
            if(*min != root->key)
            *min = root->key;
            repeat = *min;
        }
        find_min(root->right, min, repeat, compare);
    }
    return;
}

ASCII art或多或少相当于图像。

以下是一些MCVE()代码。它创建问题中所示的树。它打印一个适当的答案-元素
1
3
4
。它相当直接地实现了a中的建议,但是我没有读到那篇评论就想到了相同的算法

/* SO 5983-2999 */

#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "stderr.h"

typedef struct Tree
{
    int key;
    struct Tree *left;
    struct Tree *right;
} Tree;

typedef void (*Printer)(const Tree *node);

static void bst_print_k_smallest(Tree *tree, int k, int *count, Printer print)
{
    if (tree->left != 0)
        bst_print_k_smallest(tree->left, k, count, print);
    if (*count < k)
    {
        (*count)++;
        print(tree);
    }
    if (*count < k && tree->right != 0)
        bst_print_k_smallest(tree->right, k, count, print);
}

static void bst_print_node(const Tree *node)
{
    if (node != 0)
    {
        printf("Node: 0x%.12" PRIXPTR " - key %3d; left = 0x%.12" PRIXPTR
               ", right = 0x%.12" PRIXPTR "\n",
               (uintptr_t)node, node->key, (uintptr_t)node->left,
               (uintptr_t)node->right);
    }
}

static Tree *bst_newnode(int key)
{
    Tree *node = malloc(sizeof(*node));
    if (node == 0)
        err_syserr("failed to allocate %zu bytes of memory: ", sizeof(*node));
    node->key = key;
    node->left = node->right = 0;
    return node;
}

static Tree *bst_insert(Tree *root, int key)
{
    if (root == NULL)
        root = bst_newnode(key);
    else if (key < root->key)
        root->left = bst_insert(root->left, key);
    else if (key > root->key)
        root->right = bst_insert(root->right, key);
    /* else Repeat - ignore */
    return root;
}

static void bst_free(Tree *tree)
{
    if (tree != 0)
    {
        bst_free(tree->left);
        bst_free(tree->right);
        free(tree);
    }
}

int main(int argc, char **argv)
{
    if (argc > 0)
        err_setarg0(argv[0]);

    Tree *root = NULL;
    root = bst_insert(root,  8);
    root = bst_insert(root,  3);
    root = bst_insert(root, 10);
    root = bst_insert(root,  1);
    root = bst_insert(root,  6);
    root = bst_insert(root, 14);
    root = bst_insert(root,  4);
    root = bst_insert(root,  7);
    root = bst_insert(root, 13);

    int count = 0;
    bst_print_k_smallest(root, 3, &count, bst_print_node);

    bst_free(root);

    return 0;
}
如果将参数从3变为9,则会得到如下输出:

Node: 0x7FDC90402AF0 - key   1; left = 0x000000000000, right = 0x000000000000
Node: 0x7FDC90402AB0 - key   3; left = 0x7FDC90402AF0, right = 0x7FDC90402B10
Node: 0x7FDC90402B50 - key   4; left = 0x000000000000, right = 0x000000000000
Node: 0x7FDC90402B10 - key   6; left = 0x7FDC90402B50, right = 0x7FDC90402B70
Node: 0x7FDC90402B70 - key   7; left = 0x000000000000, right = 0x000000000000
Node: 0x7FDC90400690 - key   8; left = 0x7FDC90402AB0, right = 0x7FDC90402AD0
Node: 0x7FDC90402AD0 - key  10; left = 0x000000000000, right = 0x7FDC90402B30
Node: 0x7FDC90402B90 - key  13; left = 0x000000000000, right = 0x000000000000
Node: 0x7FDC90402B30 - key  14; left = 0x7FDC90402B90, right = 0x000000000000
如果要确保打印了所需数量的值,请选中
main()
(或调用)函数中的
count
。如果小于
k
值,则没有足够的节点来打印
k


在运行macOS Mojave 10.14.6、GCC 9.2.0和XCode 11.3.1的MacBook Pro(仍然)上进行测试。

对于任何给定的二进制搜索树,按顺序遍历将始终给出升序元素。按顺序遍历的简单方法是先访问左节点,然后访问根节点,然后访问右节点

考虑以下示例,该示例将按顺序遍历为D B E A F C G

       A
     /    \
    B      C
   / \    /  \
  D   E  F    G
简单的实现如下所示

void PrintLowestK(Tree* root, int*count, int k)
{
    if((!root)||(*count>=k)) //check whether node is not a null and already K-elements have been printed 
        return;

    PrintLowestK(root->left,count,k);//travel to the left of root

    if(*count <k){ //skewed tree or k present left side of the tree
        (*count)++;
        printf("%d ",root->key);       //print node
    }
    PrintLowestK(root->right,count,k); //travel right side of the node
}

提示:1。按顺序遍历将获得元素的升序。2.在递归访问节点时,需要传递计数和增量的引用。一旦访问的节点是
k
打印它。@顺序遍历中的TruthSeeker将始终获得升序?是,如果树是BST,则顺序遍历将给出升序。(左节点<父节点<右节点)不要将算法代码与I/O混合使用-这会造成混乱。您有
if(scanf(“%d”,&k)==1)-这只是口头上说说错误检查,因为您忽略了错误并继续,就好像什么都没有发生一样。是的,I/O很混乱;这就是为什么你要把它分开。这也意味着算法代码更容易重用。
       A
     /    \
    B      C
   / \    /  \
  D   E  F    G
void PrintLowestK(Tree* root, int*count, int k)
{
    if((!root)||(*count>=k)) //check whether node is not a null and already K-elements have been printed 
        return;

    PrintLowestK(root->left,count,k);//travel to the left of root

    if(*count <k){ //skewed tree or k present left side of the tree
        (*count)++;
        printf("%d ",root->key);       //print node
    }
    PrintLowestK(root->right,count,k); //travel right side of the node
}
int count = 0;
int k =3; //number of element to be printed 
PrintLowestK(root, &count, k);