2017-01-01 2 views
1

Ich habe bereits über das gleiche Thema gepostet. Ich bin selbstlernende Datenstrukturen mit MIT Open Courseware. Ich mache die 6.S096-Einführung in C/C++ Kurs und versuche die vierte Aufgabe.Verknüpfte Liste- find_node_data

Es basiert auf binäre Suchbäume und ich habe es versucht. Ich wollte die Werte für das Debugging drucken, aber jedes Mal verschiedene Ausführungen erhalten.

Einmal wird der Zyklus nicht abgeschlossen und das andere Mal geht es in die Unendlichkeit. Der Debugging-Block bezieht sich auch auf die andere Funktion (find_node_data) Ich muss vervollständigen. Wenn ich also herausfinden kann, was hier falsch ist, kann ich die find_node_data einfach fertigstellen. Ich habe ein paar Dinge kommentiert, um zu sehen, ob es irgendetwas betrifft. Was mache ich falsch?

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

typedef struct node{ 
    int node_id; 
    int data; 
    struct node* left; 
    struct node* right; 
}node; 



///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***/// 
// Declare the tree modification functions below... 
node* newNode(int data,int node_id){ 
    node* new_node = (node*) malloc(sizeof(node)); 
    new_node->data = data; 
    new_node->node_id= node_id; 
    new_node->right= new_node->left=NULL; 
    return new_node; 
} 

node* insert_node(node* root, int node_id, int data) { 
    if(root==NULL) 
     return newNode(data,node_id); 
    else{ 
     node* cur; 
     if(node_id<root->node_id){ 
      cur=insert_node(root->left,data,node_id); 
      root->left=cur;     
     } 
     else if(node_id>root->node_id){ 
      cur=insert_node(root->right,data,node_id); 
      root->right=cur; 
     } 
    } 
    return root; 
} 

// Find the node with node_id, and return its data 
/*int find_node_data(node* root, int node_id) { 
    node* current; 
    for(current = root->; current->next!=NULL; 
     current= current->next){ 
    if(current->data == data) return current; 
} 
return NULL; 
} 
*/ 
int main() { 
    /* 
    Insert your test code here. Try inserting nodes then searching for them. 

    When we grade, we will overwrite your main function with our own sequence of 
    insertions and deletions to test your implementation. If you change the 
    argument or return types of the binary tree functions, our grading code 
    won't work! 
    */ 
    int T,data,node_id; 
    printf("Print yo cases"); 
    scanf("%d", &T); 
    node* root = NULL; 
    while(T-->0){ 
     printf("Type yo numnums no. %d:",T); 
     scanf("%d %d",&data,&node_id); 
     root=insert_node(root,data,node_id); 
    } 
    node *lol; 
    node *king; 
    for(lol=root;lol->left!=NULL;lol=lol->left){ 
     //for(king=root;king->right!=NULL;king=king->right){ 
     printf("executed!\n"); 
     printf("%d ",lol->node_id);//,king->node_id); 
     //} 
    }  
    return 0; 
} 
+2

Es gibt keine Sprache C/C++. C und C++ sind verschiedene Sprachen. Und du solltest [fragen] lesen. Wirf auch nicht das Ergebnis von 'malloc' & friends oder' void * 'im Allgemeinen. – Olaf

+2

Bitte zeigen Sie Ihre Eingabe- und Ausgabedaten an und geben Sie an, wo sie nicht Ihren Erwartungen entspricht. –

+2

'void print (Knoten * np) { \t if (np) { \t \t drucken (np-> links); \t \t printf ("(% d,% d)", np-> knoten_id, np-> daten); \t \t drucken (np-> rechts); \t} } 'dann rufen Sie' print (root); 'auf main. – BLUEPIXY

Antwort

1

Um die node_data Sie verwenden können Rekursion finden Sie den Knoten zu finden.

node* find_node_data(node *root, int node_id) {  
    if (root == NULL) 
     return NULL; 
    else if (root->node_id == node_id) 
     return root; 
    else { 
     node *left = find_node_data(root->left, node_id); 
     return left? left: find_node_data(root->right, node_id); 
    } 
} 

Und dann die Daten für den Knoten z. erhalten die Daten für Knoten mit node_id 42:

printf("node data %d", find_node_data(root, 42)->data); 

Volles Programm unten (? Ich kann seine Richtigkeit nicht garantieren, aber vielleicht können Sie)

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

typedef struct node { 
    int node_id; 
    int data; 
    struct node *left; 
    struct node *right; 
} node; 


///*** DO NOT CHANGE ANY FUNCTION DEFINITIONS ***/// 
// Declare the tree modification functions below... 
node *newNode(int data, int node_id) { 
    node *new_node = (node *) malloc(sizeof(node)); 
    new_node->data = data; 
    new_node->node_id = node_id; 
    new_node->right = new_node->left = NULL; 
    return new_node; 
} 

node *insert_node(node *root, int data, int node_id) { 
    if (root == NULL) 
     return newNode(data, node_id); 
    else { 
     node *cur; 
     if (node_id < root->node_id) { 
      cur = insert_node(root->left, data, node_id); 
      root->left = cur; 
     } 
     else if (node_id > root->node_id) { 
      cur = insert_node(root->right, data, node_id); 
      root->right = cur; 
     } 
    } 
    return root; 
} 

// Find the node with node_id, and return its data 
/* 
int find_node_data_old(node *root, int node_id) { 
    node *current; 
    for (current = root->; current->next != NULL; 
     current = current->next) { 
     if (current->data == data) return current; 
    } 
    return NULL; 
}*/ 
node* find_node_data(node *root, int node_id) { 

    if (root == NULL) 
     return NULL; 
    else if (root->node_id == node_id) 
     return root; 
    else { 
     node *left = find_node_data(root->left, node_id); 
     return left? left: find_node_data(root->right, node_id); 
    } 
} 
void print(node *np) { 
    if (np) { 
     print(np->left); 
     printf("(%d, %d)", np->node_id, np->data); 
     print(np->right); 
    } 
} 

int main() { 
    /* 
    Insert your test code here. Try inserting nodes then searching for them. 

    When we grade, we will overwrite your main function with our own sequence of 
    insertions and deletions to test your implementation. If you change the 
    argument or return types of the binary tree functions, our grading code 
    won't work! 
    */ 
    int T, data, node_id; 
    printf("Print yo cases"); 
    scanf("%d", &T); 
    node *root = NULL; 
    while (T-- > 0) { 
     printf("Type yo numnums no. %d:", T); 
     scanf("%d %d", &data, &node_id); 
     root = insert_node(root, data, node_id); 
    } 
    node *lol; 
    node *king; 
    for (lol = root; lol->left != NULL; lol = lol->left) { 
     //for(king=root;king->right!=NULL;king=king->right){ 
     printf("executed!\n"); 
     printf("%d ", lol->node_id);//,king->node_id); 
     //} 
    } 
    print(root); 
    printf("\n"); 
    printf("node data %d", find_node_data(root, 42)->data); 
    return 0; 
} 

-Test

Print yo cases3 
Type yo numnums no. 2:22 42 
Type yo numnums no. 1:21 41 
Type yo numnums no. 0:20 40 
executed! 
42 executed! 
41 (40, 20)(41, 21)(42, 22) 
node data 22 

Sie können Verwenden Sie auch Jonathan Lefflers verbesserte Rekursion, um den Knoten zu finden:

Beide Funktionen geben die korrekten Werte wie im zweiten Test zurück.

int main() { 
    /* 
    Insert your test code here. Try inserting nodes then searching for them. 

    When we grade, we will overwrite your main function with our own sequence of 
    insertions and deletions to test your implementation. If you change the 
    argument or return types of the binary tree functions, our grading code 
    won't work! 
    */ 
    int T, data, node_id; 
    printf("Print yo cases"); 
    scanf("%d", &T); 
    node *root = NULL; 
    while (T-- > 0) { 
     printf("Type yo numnums no. %d:", T); 
     scanf("%d %d", &data, &node_id); 
     root = insert_node(root, data, node_id); 
    } 
    node *lol; 
    node *king; 
    for (lol = root; lol->left != NULL; lol = lol->left) { 
     //for(king=root;king->right!=NULL;king=king->right){ 
     printf("executed!\n"); 
     printf("%d ", lol->node_id);//,king->node_id); 
     //} 
    } 
    print(root); 
    printf("\n"); 
    printf("node data %d\n", find_node_data(root, 42)->data); 
    printf("node data find_node_data2 %d", find_node_data2(root, 42)->data); 
    return 0; 
} 

-Test 2

Print yo cases3 
Type yo numnums no. 2:11 12 
Type yo numnums no. 1:13 14 
Type yo numnums no. 0:20 42 
(12, 11)(14, 13)(42, 20) 
node data 20 
node data find_node_data2 20 
+2

Sie können einen besseren Job in 'find_node_data()' ausführen, indem Sie die geordnete Eigenschaft der Struktur verwenden: 'node * find_node_data (Knoten * root, int Knoten-ID) {if (root == NULL) return NULL; sonst if (root-> node_id == node_id) gibt root zurück; sonst if (root-> node_id> node_id) return find_node_data (root-> left, node_id); sonst Rückgabe find_node_data (root-> right, node_id); } '. Dies erspart die Jagd auf der linken Seite des Baumes, wenn sich der Knoten auf der rechten Seite befindet. Ich habe Ihren Code genommen und minimale Änderungen vorgenommen. Ich würde wahrscheinlich die Tests "if (node_id < root-> node_id)" umkehren, um zuerst aufzulisten, was getestet wird ('node_id'). –

+0

@ JonathanLeffler Danke für die interessante Verbesserung. Ich fügte die verbesserte Funktion in meine aktualisierte Antwort ein und einen Vergleich, dass beide Funktionen denselben Wert zurückgeben. Es könnte interessant sein, die Zeit für die Rekursionen zu analysieren oder zu vergleichen. –

+1

Um den Leistungsunterschied zuverlässig zu messen, benötigen Sie wahrscheinlich einen relativ großen Baum mit vielleicht hundert oder mehr Knoten. Eine Sache, um den Unterschied messen zu können: Angenommen, Sie haben einen perfekt ausgeglichenen Baum mit 15 Knoten. Wenn Sie nach dem größten Wert gesucht haben, würde Ihr Code zuerst jeden anderen Knoten besuchen, bevor er die Übereinstimmung findet. Mein Code würde nur 4 Knoten besuchen. Die Disparität wächst mit dem Wachstum des Baumes. Das ist der Extremfall, aber Ihr Code ist am besten (bei der Suche nach Werten in Blattknoten), wenn Sie nach dem kleinsten Wert suchen, aber mein Code funktioniert genauso gut. –