二叉搜索树,常量 NULL return
Binary search tree, constant NULL return
我用二叉树写了一个电话簿搜索。代码中的所有内容都运行良好,但系统提示我输入要搜索的号码时除外。然后search_phonebook函数return默认为NULL。我无法破解它是什么。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_NUM 15
#define MAX_NAME 50
typedef struct node {
char *name_and_lastname;
char *phone;
struct node *left;
struct node *right;
} Node;
Node* make_node(char *name, char* phone){
Node *new = (Node *) malloc(sizeof(Node));
if (new == NULL)
return NULL;
new->name_and_lastname = (char*)malloc((strlen(name)+1)*sizeof(char));
if( new->name_and_lastname == NULL) {
free(new);
return NULL;
}
new->phone = (char*)malloc((strlen(phone)+1)*sizeof(char));
if( new->phone == NULL) {
free(new);
return NULL;
}
strcpy(new->name_and_lastname, name);
strcpy(new->phone, phone);
new->left = NULL;
new->right = NULL;
return new;
}
void free_tree(Node ** root_adress) {
if (*root_adress == NULL)
return ;
free_tree(&(*root_adress)->left);
free_tree(&(*root_adress)->right);
free((*root_adress)->name_and_lastname);
free(*root_adress);
*root_adress = NULL;
}
void check_allocation(Node* new) {
if( new == NULL) {
fprintf(stderr, "Malloc error for new node!\n");
exit(EXIT_FAILURE);
}
}
void add_node(Node ** root_adress, char *name, char* phone) {
if( *root_adress == NULL){
Node* new = make_node(name, phone);
check_allocation( new);
*root_adress = new;
return;
}
if (strcmp((*root_adress)->name_and_lastname, name) < 0)
add_node(&(*root_adress)->right, name, phone);
else
if (strcmp((*root_adress)->name_and_lastname, name) > 0)
add_node(&(*root_adress)->left, name, phone);
}
void print_phonebook(Node * root) {
if (root == NULL)
return;
print_phonebook(root->left);
printf("%s: %s\n", root->name_and_lastname, root->phone);
print_phonebook(root->right);
}
int read_contact(FILE * f, char *name , char* phone) {
int c;
int i = 0;
int j=0;
while( (c=fgetc(f)) != EOF ) {
if ( !isdigit(c) && !ispunct(c) && c != '\n')
name[i++]=c;
if ( !isspace(c) && !isalpha(c))
phone[j++]=c;
else if ( j>0 )
break;
}
name[i]='[=11=]';
phone[j]='[=11=]';
if ( i==0 && j==0)
return EOF;
else
return 0;
}
Node* search_phonebook(Node* root, char* name) {
if(root == NULL)
return NULL;
if(strcmp(root->name_and_lastname,name) ==0 )
return root;
if( strcmp(root->name_and_lastname,name) > 0)
return search_phonebook(root->left, name);
else
return search_phonebook(root->right, name);
}
int main(int argc, char **argv) {
Node *root = NULL, *x;
FILE *f=NULL;
char name[MAX_NAME];
char phone[MAX_NUM];
char c;
int i;
if (argc < 2) {
fprintf(stderr, "Add the .txt file in the command line!\n");
exit(0);
}
if ((f = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "fopen() error\n");
exit(1);
}
while (read_contact(f, name, phone) != EOF)
add_node(&root, name, phone);
fclose(f);
print_phonebook(root);
printf("Whose number are we looking for?");
i=0;
while ((c=getchar())!='\n') name
[i++] =c ;
name[i]='[=11=]';
x = search_phonebook(root,name);
if(x == NULL)
printf("Not in the phonebook!\n");
else
printf("%s %s \n", x->name_and_lastname, x->phone);
free_tree(&root);
return 0;
}
电话簿是这样的:
Peter Peterson 84/246-654
Mark Ronson 16/245-964
Steve Rock 174/53-247
if ( !isdigit(c) && !ispunct(c) && c != '\n')
name[i++]=c;
这将包括名称末尾的空格。所以你需要搜索 "Mark Ronson " (注意末尾的空格)。或者更好的是,您应该编写代码以不在名称中包含最后一个空格。
顺便说一句,关于调试的一般提示。如果您使用调试器或只是在代码中添加了一些调试 printfs 来检查数据的有效性,您很容易发现这个问题。
我用二叉树写了一个电话簿搜索。代码中的所有内容都运行良好,但系统提示我输入要搜索的号码时除外。然后search_phonebook函数return默认为NULL。我无法破解它是什么。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX_NUM 15
#define MAX_NAME 50
typedef struct node {
char *name_and_lastname;
char *phone;
struct node *left;
struct node *right;
} Node;
Node* make_node(char *name, char* phone){
Node *new = (Node *) malloc(sizeof(Node));
if (new == NULL)
return NULL;
new->name_and_lastname = (char*)malloc((strlen(name)+1)*sizeof(char));
if( new->name_and_lastname == NULL) {
free(new);
return NULL;
}
new->phone = (char*)malloc((strlen(phone)+1)*sizeof(char));
if( new->phone == NULL) {
free(new);
return NULL;
}
strcpy(new->name_and_lastname, name);
strcpy(new->phone, phone);
new->left = NULL;
new->right = NULL;
return new;
}
void free_tree(Node ** root_adress) {
if (*root_adress == NULL)
return ;
free_tree(&(*root_adress)->left);
free_tree(&(*root_adress)->right);
free((*root_adress)->name_and_lastname);
free(*root_adress);
*root_adress = NULL;
}
void check_allocation(Node* new) {
if( new == NULL) {
fprintf(stderr, "Malloc error for new node!\n");
exit(EXIT_FAILURE);
}
}
void add_node(Node ** root_adress, char *name, char* phone) {
if( *root_adress == NULL){
Node* new = make_node(name, phone);
check_allocation( new);
*root_adress = new;
return;
}
if (strcmp((*root_adress)->name_and_lastname, name) < 0)
add_node(&(*root_adress)->right, name, phone);
else
if (strcmp((*root_adress)->name_and_lastname, name) > 0)
add_node(&(*root_adress)->left, name, phone);
}
void print_phonebook(Node * root) {
if (root == NULL)
return;
print_phonebook(root->left);
printf("%s: %s\n", root->name_and_lastname, root->phone);
print_phonebook(root->right);
}
int read_contact(FILE * f, char *name , char* phone) {
int c;
int i = 0;
int j=0;
while( (c=fgetc(f)) != EOF ) {
if ( !isdigit(c) && !ispunct(c) && c != '\n')
name[i++]=c;
if ( !isspace(c) && !isalpha(c))
phone[j++]=c;
else if ( j>0 )
break;
}
name[i]='[=11=]';
phone[j]='[=11=]';
if ( i==0 && j==0)
return EOF;
else
return 0;
}
Node* search_phonebook(Node* root, char* name) {
if(root == NULL)
return NULL;
if(strcmp(root->name_and_lastname,name) ==0 )
return root;
if( strcmp(root->name_and_lastname,name) > 0)
return search_phonebook(root->left, name);
else
return search_phonebook(root->right, name);
}
int main(int argc, char **argv) {
Node *root = NULL, *x;
FILE *f=NULL;
char name[MAX_NAME];
char phone[MAX_NUM];
char c;
int i;
if (argc < 2) {
fprintf(stderr, "Add the .txt file in the command line!\n");
exit(0);
}
if ((f = fopen(argv[1], "r")) == NULL) {
fprintf(stderr, "fopen() error\n");
exit(1);
}
while (read_contact(f, name, phone) != EOF)
add_node(&root, name, phone);
fclose(f);
print_phonebook(root);
printf("Whose number are we looking for?");
i=0;
while ((c=getchar())!='\n') name
[i++] =c ;
name[i]='[=11=]';
x = search_phonebook(root,name);
if(x == NULL)
printf("Not in the phonebook!\n");
else
printf("%s %s \n", x->name_and_lastname, x->phone);
free_tree(&root);
return 0;
}
电话簿是这样的:
Peter Peterson 84/246-654
Mark Ronson 16/245-964
Steve Rock 174/53-247
if ( !isdigit(c) && !ispunct(c) && c != '\n')
name[i++]=c;
这将包括名称末尾的空格。所以你需要搜索 "Mark Ronson " (注意末尾的空格)。或者更好的是,您应该编写代码以不在名称中包含最后一个空格。
顺便说一句,关于调试的一般提示。如果您使用调试器或只是在代码中添加了一些调试 printfs 来检查数据的有效性,您很容易发现这个问题。