搜索二叉树并打印有价值的孩子

时间:2010-11-12 18:13:40

标签: c data-structures recursion binary-tree

所以我在过去两周里花了很多不眠之夜试图研究我认为简单的程序:我试图从特定文件中的整数列表创建二进制树。数字将插入二叉树中。然后,我提示用户输入值以查看是否是节点。如果是,那么我打印搜索值的左右子。不幸的是,我不能为我的生活让我的代码工作。非常感谢任何帮助!

#define kFileName   "../../Data.txt"

struct Node {
    int           number;
    struct Node   *left, *right;
};

extern struct Node *gRootNodePtr;
void    BuildTree( void );
int     GetNumberFromFile( int *numPtr, FILE *fp );
void    InsertInTree( int num );
void    AddNode( struct Node *newNodePtr, struct Node **curNodePtrPtr );
void    SearchTree( int num, struct Node *nodePtr );
void    PrintChild( struct Node *nodePtr );

void InsertInTree(int num) {
    struct Node *nodePtr;

    nodePtr = malloc(sizeof(struct Node));

    if (nodePtr == NULL)
        DoError("Could not allocate memory!\n");

    nodePtr->number = num;
    nodePtr->left = NULL;
    nodePtr->right = NULL;

    AddNode(nodePtr, &gRootNodePtr);
}

void AddNode(struct Node *newNodePtr, struct Node **curNodePtrPtr) {
    if (*curNodePtrPtr == NULL)
        *curNodePtrPtr = newNodePtr;
    else if (newNodePtr->number < (*curNodePtrPtr)->number)
        AddNode(newNodePtr, &((*curNodePtrPtr)->left));
    else
        AddNode(newNodePtr, &((*curNodePtrPtr)->right));
    }

void SearchTree(int num, struct Node *nodePtr) {
    if (nodePtr == NULL)
        return;

    printf("Enter number to be searched: ");
    scanf("%d", &num);
    SearchTree(num, nodePtr);
    PrintChild(nodePtr->left);
    printChild(nodePtr->right);
}

void PrintChild( struct Node *nodePtr) {
    printf("%d ", nodePtr->number);
}

void BuildTree(void) {
    int     num;
    FILE    *fp;

    if ((fp = fopen( kFileName, "r")) == NULL)
        printf("Could not read numbers file!\n");

    printf("Numbers:   ");

    while (GetNumberFromFile( &num, fp )) {
        printf("%d, ", num);
        InsertInTree(num);
    }

    printf("\n-------\n");

    fclose(fp);
}

int GetNumberFromFile(int *numPtr, FILE *fp)
{
    if (fscanf(fp, "%d\n", numPtr) == EOF)
        return false;
    else
        return true;
}

int main(int argc, char* argv[]) {
    gRootNodePtr = NULL;
    int num=NULL;
    BuildTree();
    NodePtr SearchTree(num, gRootNodePtr);

return;
}

7 个答案:

答案 0 :(得分:1)

这是一个足够不同的东西,它不仅直接给你答案,而且足够相似,它可能提供一些帮助和/或灵感。只是为了咧嘴笑,这表明了递归和迭代树遍历。

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

typedef struct node {
    struct node *left;
    struct node *right;
    char *string;
} node;

node *root; /* automatically initialized to NULL */

node *make_node(char const *string) {
    node *ret = malloc(sizeof(node));
    if (ret == NULL)
        return NULL;
    ret->string = malloc(strlen(string) + 1);
    if (ret->string == NULL) {
        free(ret);
        return NULL;
    }
    strcpy(ret->string, string);
    ret->left = NULL;
    ret->right = NULL;
    return ret;
}

void del_node(node *node) {
    free(node->string);
    free(node);
}

int insert(const char *string, node **root) {
    if (*root == NULL)
        *root = make_node(string);
    else {
        node *iter = *root;
        for(;;) {
            int cmp = strcmp(string, iter->string);
            if ( 0 == cmp)
                /* duplicate string - ignore it. */
                return 0;
            else if (1 == cmp) {
                if (NULL == iter->right ) {
                    iter->right = make_node(string);
                    break;
                }
                else iter=iter->right;
            }
            else if ( NULL == iter->left ) {
                iter->left = make_node(string);
                break;
            }
            else
                iter = iter->left;
        }
    }
    return 1;
}

void print(node *root) {
    if (root->left != NULL )
        print(root->left);
    fputs(root->string, stdout);
    if ( root->right != NULL )
        print(root->right);
}

int main() {
    char line[100];

    while (fgets(line, 100, stdin))
        insert(line, &root);
    print(root);
    return 0;
}

答案 1 :(得分:0)

走几步。

创建新功能PrintLeaves。根据所需的更改,将main修改为

int main() {
    InsertInTree(42);
    PrintLeaves();
    return 0;
}

并调整它直到你打印出42 然后添加几个随机InsertInTree ...并调整...

答案 2 :(得分:0)

SearchTree错误可能源于它在main()中的使用。什么是NodePtr在那里做? SearchTree声明为void。此外,您指针的整数可能是由于您使用NULL,可能是(void *)0。使用

int num = 0;

答案 3 :(得分:0)

你并没有确切地说它是如何起作用的,但很明显你不应该在你的递归SearchTree例程中提示要搜索的值。

除此之外,看起来你很近。尝试这样的事情:

    void    SearchTree( int num, struct Node *nodePtr ) {
        if ( nodePtr == NULL )
            return;

        if (NodePtr->Number == num)
        {
           PrintChild( nodePtr->left );
           PrintChild( nodePtr->right );
        }
        else
        {
          SearchTree(num, nodePtr->left );
          SearchTree(num, nodePtr->right );
        }
    }

答案 4 :(得分:0)

在不深入研究代码的情况下,以下是通常用于递归搜索BST的方法:

(伪代码)

visit(node,value):
   if node is null: // empty tree
       return
   if node->key==value: // found one
       // do whatever it is you want to do with it
   if node->key<=value: // less than or equal keys are to the left 
      visit(node->left,value)
   else: // greater keys are to the right
      visit(node->right,value)  

答案 5 :(得分:0)

我编译了你的代码。它甚至做了一些事情。我试着不要碰太多。只是为了做到这一点,因为代码中没有二叉树,并且不清楚它的用途。请参阅下面的代码。但在那之前: 1.您没有构建二叉树,而是在构建链接列表。也许,您需要排序数字的双链表?如果是,我在这里发布的代码不会对它进行排序,仅供参考。 2.也许,你特意在这里发布堆栈溢出有害代码,但是你应该关心用户输入,指针和其他所有东西(其他用户都有很好的答案)。 3.最后,你想做什么?

代码

#include <stdio.h>
#include <malloc/malloc.h>
#define kFileName   "Data.txt"

struct Node {
    int         number;
    struct Node     *left, *right;
};

struct Node *gRootNodePtr;

void    BuildTree( void );
int     GetNumberFromFile( int *numPtr, FILE *fp );
void    InsertInTree( int num );
void    AddNode( struct Node *newNodePtr, struct Node **curNodePtrPtr );
void    SearchTree( int num, struct Node *nodePtr );
void    PrintChild( struct Node *nodePtr );

void    InsertInTree( int num ) {
    struct Node *nodePtr;

    nodePtr = (struct Node *) malloc( sizeof( struct Node ) );

    if ( nodePtr == NULL ) {
        printf("Could not allocate memory!\n" );
                return;
        }

    nodePtr->number = num;
    nodePtr->left = NULL;
    nodePtr->right = NULL;

    AddNode( nodePtr, &gRootNodePtr );
}

void    AddNode( struct Node *newNodePtr, struct Node **curNodePtrPtr ) {
if ( *curNodePtrPtr == NULL )
        *curNodePtrPtr = newNodePtr;
    else if ( newNodePtr->number < (*curNodePtrPtr)->number )
        AddNode( newNodePtr, &( (*curNodePtrPtr)->left ) );
    else
        AddNode( newNodePtr, &( (*curNodePtrPtr)->right ) );
}

void search(struct Node * nodePtr) {
        int num;
    printf("Enter number to be searched: ");
    scanf("%d", &num);
        SearchTree(num, nodePtr);
}

void  SearchTree(int num, struct Node *nodePtr ) {
    if ( nodePtr == NULL )
        return;

        if(num == nodePtr->number) {
            if(nodePtr->left != NULL) PrintChild(nodePtr->left);
            PrintChild(nodePtr);
            if(nodePtr->right != NULL) PrintChild(nodePtr->right);
            printf("\n");
            return;
        } else if(num > nodePtr->number) {
            SearchTree(num, nodePtr->right);
        } else {
            SearchTree(num, nodePtr->left);
        }
}

void    PrintChild( struct Node *nodePtr ) {
    printf( "%d ", nodePtr->number );
}

void    BuildTree( void )
{
    int     num;
    FILE    *fp;

    if ( ( fp = fopen( "Data.txt", "r" ) ) == NULL )
        printf( "Could not read numbers file!\n" );

    printf( "Numbers:   " );

    while ( GetNumberFromFile( &num, fp ) )
    {
        printf( "%d, ", num );
        InsertInTree( num );
    }

    printf( "\n-------\n" );

    fclose( fp );
}

int GetNumberFromFile( int *numPtr, FILE *fp )
{
    if ( fscanf( fp, "%d\n", numPtr ) == EOF )
        return false;
    else
        return true;
}

int main(int argc, char* argv[])
{
    gRootNodePtr = NULL;
    BuildTree();
        search(gRootNodePtr);
        return;
}

答案 6 :(得分:0)

php中的

This is my code for binary tree and all of its操作:

<?php

类节点 {  公共数据;  public $ leftChild;  public $ rightChild;

public function __construct($ data)   {    $这 - &GT;数据= $数据;    $这 - &GT; leftChild = NULL;    $这 - &GT; rightChild = NULL;   }  公共函数disp_data()   {    echo $ this-&gt; data;   }

} //结束类节点 class BinaryTree {  public $ root;  // public $ s;  公共函数__construct()   {    $这 - &GT;根= NULL;    // $这 - &GT; S =的file_get_contents( '存储');

} //用于显示树的功能   公共功能显示()   {    $这 - &GT; display_tree($这 - &GT;根);

}   public function display_tree($ local_root)   {

如果($ local_root == NULL)      返回;     $这 - &GT; display_tree($ local_root-&GT; leftChild);     echo $ local_root-&gt; data。“
”;     $这 - &GT; display_tree($ local_root-&GT; rightChild);

} //用于插入新节点的功能   公共函数插入($ key)    {     $ newnode = new Node($ key);       如果($这 - &GT;根== NULL)         {          $这 - &GT;根= $ newnode;          返回;         }       其他         {          $父= $这 - &GT;根;          $电流= $这 - &GT;根;            而(真)              {                $父= $电流;                  // $这 - &GT; find_order($键,$电流 - &GT;数据);                 如果($键==($这 - &GT; find_order($键,$电流 - &GT;数据)))                   {                       $电流= $电流 - &GT; leftChild;                        如果($当前== NULL)                          {                           $父 - &GT; leftChild = $ newnode;                           返回;                          } //结束if2                   } //结束if1                 其他                   {                       $电流= $电流 - &GT; rightChild;                        如果($当前== NULL)                          {                           $父 - &GT; rightChild = $ newnode;                           返回;
                         } //结束if1
                  } //结束其他              } //结束while循环         } //结束其他

} //结束插入功能

//搜索特定节点的功能  公共功能查找($ key)   {     $电流= $这 - &GT;根;      而($电流 - &GT;!数据= $键)           {             如果($键== $这 - &GT; find_order($键,$电流 - &GT;数据))               {                 $电流= $电流 - &GT; leftChild;               }             其他               {                 $电流= $电流 - &GT; rightChild;               }             如果($当前== NULL)               返回(NULL);

      }
     return($current->data); 

} //结束要搜索的功能  公共函数delete1($ key)   {     $电流= $这 - &GT;根;     $父= $这 - &GT;根;

$isLeftChild=true;
 while($current->data!=$key)
      {
       $parent=$current;
       if($key==($this->find_order($key,$current->data)))
         {
          $current=$current->leftChild;
          $isLeftChild=true;
         }   
       else
         {
          $current=$current->rightChild;
          $isLeftChild=false;   
         } 
        if($current==null)
          return(null);
      }//end while loop 

  echo "<br/><br/>Node to delete:".$current->data;
 //to delete a leaf node 
 if($current->leftChild==null&&$current->rightChild==null)
   {
       if($current==$this->root)
          $this->root=null;  
      else if($isLeftChild==true)
       {
        $parent->leftChild=null;
       }  
     else
       {
        $parent->rightChild=null;
       }
     return($current);       
   }//end if1
 //to delete a node having a leftChild 

else if($ current-&gt; rightChild == null)        {           如果($当前== $这 - &GT;根)            $这 - &GT;根= $电流 - &GT; leftChild;           else if($ isLeftChild == true)            {             $父 - &GT; leftChild = $电流 - &GT; leftChild;            }           其他            {             $父 - &GT; rightChild = $电流 - &GT; leftChild;            }
          返回($电流);        } //结束其他if1     //删除具有rightChild的节点    否则if($ current-&gt; leftChild == null)        {          如果($当前== $这 - &GT;根)            $这 - &GT;根= $电流 - &GT; rightChild;          else if($ isLeftChild == true)            {             $父 - &GT; leftChild = $电流 - &GT; rightChild;            }
         其他            {             $父 - &GT; rightChild = $电流 - &GT; rightChild;            }
           返回($电流);        }
   //删除具有两个子节点的节点     其他        {         $后继= $这 - &GT; get_successor($电流);         如果($当前== $这 - &GT;根)           {             $这 - &GT;根= $后继;

      }
    else if($isLeftChild==true)
      {
       $parent->leftChild=$successor;
      }
    else
      {
       $parent->rightChild=$successor;
      }     
     $successor->leftChild=$current->leftChild;
    return($current);
   }   

} //结束删除节点的功能 //查找后继节点的函数  public function get_successor($ delNode)   {    $ succParent = $ delNode;    $继任= $ delNode;    $温度= $ delNode-&GT; rightChild;     而($温度!= NULL)          {           $ succParent = $继任者;           $继任= $温度;           $温度= $ TEMP-&GT; leftChild;          }    如果($继任= $ delNode-&GT;!rightChild)      {       $ succParent-&GT; leftChild = $ successor-&GT; rightChild;       $ successor-&GT; rightChild = $ delNode-&GT; rightChild;      }   回报($继任者);   } //函数查找两个字符串的顺序  public function find_order($ str1,$ str2)   {      $ STR1 =用strtolower($ STR1);      $ STR2 =用strtolower($ STR2);      $ I = 0;      $ J = 0;

 $p1=$str1[i];
 $p2=$str2[j]; 

而(真)    {
       如果(ORD($ P1)

       return($str1);
     }
  else
     {
       if(ord($p1)==ord($p2))
         {
          $p1=$str1[++$i];
          $p2=$str2[++$j];
          continue;
         }
      return($str2); 
     }

} //结束时

} //结束函数查找字符串顺序

公共职能is_empty()   {     如果($这 - &GT;根== NULL)       返回(真);     其他       返回(假);   } } //结束类BinaryTree ?&GT;