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);