Ищите бинарное дерево и печатайте ценных детей - PullRequest
0 голосов
/ 12 ноября 2010

Итак, я провел много бессонных ночей в последние две недели, пытаясь поработать над тем, что, по моему мнению, было бы простой программой: я пытаюсь создать двоичное дерево из списка целых чисел в определенном файле.Числа вставляются в двоичное дерево.Затем я запрашиваю у пользователя значение для поиска, если это узел.Если это так, я печатаю левый и правый дочерний элемент искомого значения.Я, к сожалению, не могу за всю жизнь заставить мой код работать.Любая помощь с благодарностью!

#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 ]

1 голос
/ 12 ноября 2010

Вот тот, который достаточно отличается, что он не просто дает вам ответ напрямую, но достаточно похож, чтобы он мог предоставить некоторую помощь и / или вдохновениеТолько для улыбок, это демонстрирует как рекурсивный, так и итерационный обход дерева.

#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;
}
0 голосов
/ 05 декабря 2010

This is my code for binary tree and all of its операций в php:

<?php

class Node {public $ data;public $ leftChild;public $ rightChild;

открытая функция __construct ($ data) {$ this-> data = $ data;$ This-> LeftChild = NULL;$ This-> RightChild = NULL;} публичная функция disp_data () {echo $ this-> data;}

} // конец класса Node class BinaryTree {public $ root;// public $ s;публичная функция __construct () {$ this-> root = null;// $ this-> s = file_get_contents ('store');

} // функция для отображения дерева публичная функция display () {$ this-> display_tree ($ this-> root);

} открытая функция display_tree ($ local_root) {

if ($ local_root == null) return;$ This-> display_tree ($ local_root-> LeftChild);echo $ local_root-> data. ""; $ this-> display_tree ($ local_root-> rightChild);

} // функция для вставки новой функции узла. public ($ key) {$ newnode = new Node ($ key); if ($ this-> root == null) {$ this-> root = $ newnode; return;} else {$ parent = $ this-> root; $ current = $ this-> root; while (true) {$ parent =$ current; // $ this-> find_order ($ key, $ current-> data); if ($ key == ($ this-> find_order ($ key, $ current-> data))) {$ current = $current-> leftChild; if ($ current == null) {$ parent-> leftChild = $ newnode; return;} // end if2} // end if1 else {$ current = $ current-> rightChild; if ($ current== null) {$ parent-> rightChild = $ newnode; return;
} // end if1
} // end else} // конец цикла} // end else

}// конец функции вставки

// функция для поиска определенной публичной функции Node find ($ key) {$ current = $ this-> root; while ($ current-> data! = $ key) {if($ key == $ this-> find_order ($ key, $ current-> data)) {$ current = $ current-> leftChild;} else {$ current = $ current-> rightChild;} if ($ current ==null) return (null);

      }
     return($current->data); 

} // завершаем функцию для поиска публичной функции delete1 ($ key) {$ current = $ this-> root;$ parent = $ this-> root;

$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-> rightChild == null) {if ($ current == $ this-> root) $ this-> root = $current-> LeftChild;иначе if ($ isLeftChild == true) {$ parent-> leftChild = $ current-> leftChild;} else {$ parent-> rightChild = $ current-> leftChild;}
return ($ current);} // конец else if1 // для удаления узла, имеющего rightChild else if ($ current-> leftChild == null) {if ($ current == $ this-> root) $ this-> root = $ current->RightChild;иначе if ($ isLeftChild == true) {$ parent-> leftChild = $ current-> rightChild;}
else {$ parent-> rightChild = $ current-> rightChild;}
return ($ current);}
// чтобы удалить узел, имеющий обоих потомков else {$ successor = $ this-> get_successor ($ current);if ($ current == $ this-> root) {$ this-> root = $ successor;

      }
    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-> RightChild;while ($ temp! = null) {$ succParent = $ successor;$ Правопреемника = $ темп; $ Темп = $ TEMP-> LeftChild; } если ($ преемник! = $ delNode-> RightChild) { $ SuccParent-> LeftChild = $ successor-> RightChild; $ Successor-> RightChild = $ delNode-> RightChild; } Возвращение ($ правопреемник); } // функция для поиска порядка двух строк публичная функция find_order ($ str1, $ str2) { $ Str1 = strtolower ($ str1); $ Str2 = strtolower ($ str2); $ I = 0; $ J = 0;

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

в то время (правда) {
если (ог ($ p1)

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

} // конец пока

} // конец функции поиска порядка строк

публичная функция is_empty () { если ($ this-> корень == NULL) вернуться (истина); еще возвращать (ложь); } } // конец класса BinaryTree ?>

0 голосов
/ 12 ноября 2010

Я получил ваш код скомпилирован. Это даже что-то делает. Я старался не трогать это слишком сильно. Просто чтобы сделать что-то, потому что в вашем коде нет бинарных деревьев, и неясно, для чего он предназначен. Смотрите код ниже. Но до этого: 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;
}
0 голосов
/ 12 ноября 2010

Не углубляясь в ваш код, вот как обычно рекурсивно выполняется поиск по 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)  
0 голосов
/ 12 ноября 2010

Вы не говорите точно, как это не работает, но совершенно ясно, что вам не следует запрашивать значение для поиска из вашей рекурсивной подпрограммы 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 );
        }
    }
0 голосов
/ 12 ноября 2010

Ошибка SearchTree может быть следствием ее использования в main ().Что там делает NodePtr?SearchTree объявлен недействительным.Кроме того, ваше целое число из указателя может быть связано с использованием NULL, который может быть (void *) 0.Используйте

int num = 0;
0 голосов
/ 12 ноября 2010

Идите небольшими шагами.

Создайте новую функцию PrintLeaves.С необходимыми изменениями измените ваш main на

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

и настройте его, пока не получите 42 отпечатка.
Затем добавьте еще несколько случайных InsertInTree ... и настройте ...

...