简体   繁体   English

如何在C中将数字插入二进制搜索树?

[英]How to insert numbers into a binary search tree in C?

I am trying to insert a list of numbers into a binary search tree by calling the TREEinsert function frim the main function however whenever my program runs it does not print any number inserted into the binary search tree. 我试图通过调用main函数的TREEinsert函数将数字列表插入二进制搜索树中,但是无论何时我的程序运行,它都不会打印任何插入二进制搜索树中的数字。 I have gone over both my TREEinsert function and Displayinorder function but cannot seem to find any issues with the functionality of either function. 我已经遍历了TREEinsert函数和Displayinorder函数,但是似乎找不到任何一个函数的问题。 I have a basic understanding of binary search trees and have looked at many examples trying to get an insight as to how BST's work. 我对二进制搜索树有基本的了解,并查看了许多示例,以期了解BST的工作原理。 Any guidance will be greatly helpful. 任何指导将大有帮助。

struct node
 {
     int info;
     struct node *left;
     struct node *right;
 };



void TREEclear(struct node* t)
{
     t = NULL;
}

void TREEinsert(struct node*  t, int x)
{

    //insert in BST
    if(t == NULL)
    {
        t = (struct node*)malloc(sizeof(struct node));
        t->info = x;
        t->left = NULL;
        t->right = NULL;
    }
    else
    {
        if (x < t->info)
        TREEinsert(t->left, x);
        if (x > t->info)
            TREEinsert(t->right, x);
    }
}

void Displayinorder(struct node* t)
{
    //in order: (LC)(P)(RC)
    if (t != NULL)
    {
        Displayinorder(t->left); //LC
        printf("%d\t", t->info); //P
        Displayinorder(t->right); //RC
    }
}

struct node *root;

int main()
{
    TREEclear(root);

    TREEinsert(root, 5);
    TREEinsert(root, 8);
    TREEinsert(root, 2);
    TREEinsert(root, 6);

    Displayinorder(root);

    printf("\n\n");
    system("PAUSE");
    return 0;
 }

The node pointer t is a local variable in TREEinsert . 节点指针tTREEinsert的局部变量。 Any changes you make to it are not reflected in the calling function. 您对其所做的任何更改都不会反映在调用函数中。

You should pass the address of the root pointer as struct node *p from the calling function. 您应该从调用函数将根指针的地址作为struct node *p传递。 When you recurse, pass the adress of the left or right pointer of te current node respectively. 递归时,分别传递当前节点的左指针或右指针的地址。

Here's how: 这是如何做:

#include <stdlib.h>
#include <stdio.h>

struct node {
    int info;
    struct node *left;
    struct node *right;
};


void TREEclear(struct node *t)
{
    t = NULL;
}

void TREEinsert(struct node **t, int x)
{
    if (*t == NULL) {
        *t = malloc(sizeof(**t));
        // TODO: check allocation success

        (*t)->info = x;
        (*t)->left = NULL;
        (*t)->right = NULL;
    } else {
        if (x < (*t)->info) TREEinsert(&(*t)->left, x);
        if (x > (*t)->info) TREEinsert(&(*t)->right, x);
    }
}

void Displayinorder(struct node *t)
{
    if (t != NULL) {
        Displayinorder(t->left);
        printf("%d\n", t->info);
        Displayinorder(t->right);
    }

}

int main()
{
    struct node *root = NULL;

    TREEinsert(&root, 5);
    TREEinsert(&root, 8);
    TREEinsert(&root, 2);
    TREEinsert(&root, 6);

    Displayinorder(root);

    // TODO: need to free the tree nodes

    return 0;
}

Note that you pass &root to the insertion function, which may have to modify it, but just root to the display functon, which only has to inspect it. 请注意,您将&root传递给了插入功能,该功能可能需要对其进行修改,而只是将root传递给显示功能,该功能仅需对其进行检查。

I've gotten rid of your TREEclear function. 我已经摆脱了您的TREEclear函数。 First, it has the same problems as your original TREEinsert : it modifies a local variable and doesn't change anything in main . 首先,它与原始TREEinsert存在相同的问题:它修改了局部变量,而在main中没有任何改变。 Second, this function should free all nodes, not just set the root to NULL . 其次,此函数应free所有节点,而不仅仅是将根节点设置为NULL (That said, you should write this function, so that you can deallocate the tree after use.) (也就是说,您应该编写此函数,以便可以在使用后取消分配树。)

The t in your TREEinsert function is a local variable so from there you have two options: either you return it and have the code like below, or your parameter t should be a struct node** TREEinsert函数中的t是一个局部变量,因此从那里有两个选择:要么返回它并具有下面的代码,要么参数t应该是一个struct node**
So first option is: 所以第一个选择是:

 struct node* TREEinsert(struct node*  t, int x)
 {

  //insert in BST
  if(t == NULL)
  {

    t = (struct node*)malloc(sizeof(struct node));
    t->info = x;
    t->left = NULL;
    t->right = NULL;
    return t ;
  }
 else
  {
    if (x < t->info)
        return(TREEinsert(t->left, x));
    if (x > t->info)
       return(TREEinsert(t->right, x));
  }


}

Second option is: 第二种选择是:

void TREEinsert(struct node **t, int x)
{
    if (*t == NULL) {
        *t = malloc(sizeof(**t));
        (*t)->info = x;
        (*t)->left = NULL;
        (*t)->right = NULL;
    } else {
        if (x < (*t)->info) 
            TREEinsert(&(*t)->left, x);
        if (x > (*t)->info) 
            TREEinsert(&(*t)->right, x);
    }
}

Side-note: you may want to check whether your malloc succeeded or not. 旁注:您可能要检查您的malloc是否成功。

First of all function TREEclear does not set to zero the original head of three. 首先,函数TREEclear不会将原始的3的头设置为零。 It deals with a copy of the head. 它处理一个头部的副本。 The original head is not changed. 原始磁头未更改。

Also the name of the function is confusing. 函数的名称也令人困惑。 It is better to name it for example like TREEinit . 最好将其命名为TREEinit

It can look the following way 它可以看起来如下

void TREEinit( struct node * *t)
{
    *t = NULL;
}

Recursive function TREEinsert can look like 递归函数TREEinsert看起来像

void TREEinsert( struct node * *t, int x )
{
    if ( *t == NULL )
    {
        *t = ( struct node* )malloc( sizeof( struct node ) );
        ( *t )->info = x;
        ( *t )->left = NULL;
        ( *t )->right = NULL;
    }
    else if (  x < ( *t )->info )
    {       
        TREEinsert( &( *t )->left, x );
    }
    else if ( x > ( *t )->info )
    {
        TREEinsert( &( *t )->right, x );
    }
}

and it should be called like 它应该被称为

TREEinsert( &root, 5 );

Take into account that you need to write also a function that will free all allocated memory for the tree. 考虑到您还需要编写一个函数,该函数将为树释放所有分配的内存。

There is two way to fixed it
1. change the return type of Insert function 


Struct node * TREEinsert(){
              //your code

            return the local variable( t)
           }

2. If you don't want to change the return type of function then change the argument you are passing to Insert function
            TREEinsert(&root, intVariable);
    and in  TREEinsert(Struct node **,int);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM