修改后的二叉树,就大仙解惑》》 = =,
我修改后的二叉树,应该可以在任何c和c++的编译器下成功运行,只需要修改成.c或者.cpp,但是在运行过程中还是发现了一些问题,求大家帮忙解决,1,连续输入addone命令添加结点,会出现此结点已经存在的提示,在我的程序中也就是姓名相同,但我明明输入的是不同的名字,
2,输入非addone的命令后,下一个命令前有一个无效输入,也就是说,第一次输入命令无效,也就是你输入任何字符串之后或者直接输入enter,但任何东西都不会发生,第二次你输入的命令才会被读取。
3.使用deleteone 命令会发生内存不可读的错误,以至于程序崩溃。
程序代码:
/*执行函数*/ #include <stdio.h> #include <string.h> #include "tree.h" enum allchoices {addone,deleteone,itemcount,search,showall,cleanall}; const char * choices[]={"addone","deleteone","itemcount","search","showall","cleanall"}; #define LEN 15 void menu(void); void AddOne (Tree *ptree); void DeleteOne(Tree *ptree); void ItemCount(const Tree *ptree); void FindOne(const Tree *ptree); void ShowAll(const Tree *ptree); void CleanAll(Tree *ptree); void PrintItem(Item item); int main(void) { Tree classmates; char yourchoice[LEN]; enum allchoices choice; int the_order_iseffective=0; InitializeTree(&classmates); menu(); while(strcmp(gets(yourchoice),"quit")!=0&&yourchoice[0]!='\0') { for(choice=addone;choice<=cleanall;choice=(allchoices)(choice+1)) { if(strcmp(yourchoice,choices[choice])==0) { the_order_iseffective=1; break; } } if(the_order_iseffective) switch (choice) { case (addone): AddOne(&classmates); //有效的输入命令, break; case (deleteone):DeleteOne(&classmates); break; case(itemcount):ItemCount(&classmates); break; case(search):FindOne(&classmates); break; case(showall):ShowAll(&classmates); break; case(cleanall):CleanAll(&classmates); break; } else printf("i don\'t know what the order mean!\n"); the_order_iseffective=0; puts("next order\n"); menu(); while(getchar()!='\n') continue; } puts("good job\n"); return 0; } void menu(void) { puts("please chioce what do you want to to?\n"); puts("enter \"addone\" to add a classmate.\n"); puts("enter \"deleteone\" to delete a classmate\n"); puts("enter \"itemcount\" to konw the number of your classmatas\n"); puts("enter \"search\" to find your classmate\n"); puts("enter\"showall\"to printf all of your classmates.\n"); puts("enter \"cleanall\"to chean all items. \n"); puts("enter \"quit\" to quit\n"); } void AddOne (Tree *ptree) { Item temp; if(TreeIsFull(ptree)) puts("no room to accept a new one!\n"); else { puts("please enter your classmate\'s name:\n"); gets(temp.name); puts("please enter sex of your classmate:\n"); gets(temp.sex); puts("please enter age of your classmate:\n"); scanf("%d",&temp.age); AddItem(&temp,ptree); } } void DeleteOne(Tree *ptree) { Item temp; if(TreeIsEmpty(ptree)) { puts("no members to put out!\n"); return; } puts("please enter name of classmate you want to delete:\n"); gets(temp.name); if(DeleteItem(&temp,ptree)) printf("sccessfully\n"); else puts("is not a members\n"); } void ItemCount(const Tree *ptree) { int number; number=TreeItemCount(ptree); printf("there are %d classmates\n",number); } void FindOne(const Tree *ptree) { Item temp; if(TreeIsEmpty(ptree)) { puts("no information in the tree!"); return; } puts("please enter name of classmate you want to find:\n"); gets(temp.name); if(InTree(&temp,ptree)) puts("is a member in the class!"); else puts("is not a member"); } void ShowAll(const Tree *ptree) { if(TreeIsEmpty(ptree)) { puts("no information in the tree!\n"); return; } else Traverse(ptree,PrintItem); } void CleanAll(Tree *ptree) { DeleteAll(ptree); printf("just clean all\n"); } void PrintItem(Item item) { printf("name:%s,\tsex:%s,\tage:%d\n",item.name,item.sex,item.age); }
程序代码:
/*头文件 tree.h */ #ifndef _TREE_H_ #define _TREE_H_ #define SIZE 15 #define MAXSIZE 15 typedef struct item { char name[SIZE]; char sex[SIZE]; int age; } Item; typedef struct node { Item item; struct node * left; struct node * right; } Node; typedef struct tree { Node *root; int size; } Tree; typedef struct pair { Node * parent; Node * child; }Pair; void InitializeTree(Tree *ptree); int TreeIsEmpty(const Tree *ptree); int TreeIsFull(const Tree *ptree); int TreeItemCount(const Tree*ptree); int AddItem(const Item *pitem,Tree *ptree); int InTree(const Item *pitem,const Tree *ptree); int DeleteItem(const Item *pitem,Tree *ptree); void Traverse(const Tree *ptree,void(*pun)(Item item)); void DeleteAll(Tree *ptree); #endif // _TREE_H_
程序代码:
/*实现头文件功能 tree.c*/ #include <string.h> #include <stdio.h> #include <stdlib.h> #include "tree.h" static Node * MakeNode(const Item *pitem); static int ToLeft(const Item *pitem1,const Item *pitem2); static int ToRight(const Item *pitem1,const Item *pitem2); static void AddNode(Node * new_node,Node *root); static void TraverseTree(const Node *root,void (*pfun)(Item item)); static Pair SeekItem(const Item *pitem,const Tree *ptree); static void DeleteNode(Node **pt); static void DeleteAllNode(Node *root); void InitializeTree(Tree *ptree) { ptree->root=NULL; ptree->size=0; } int TreeIsEmpty(const Tree *ptree) { if(ptree->root==NULL) return 1; else return 0; } int TreeIsFull(const Tree *ptree) { if(ptree->size==MAXSIZE) return 1; else return 0; } int TreeItemCount(const Tree *ptree) { return ptree->size; } int AddItem(const Item *pitem,Tree *ptree) { Node *new_node; if(SeekItem(pitem,ptree).child!=NULL) { printf("the item is already exist.\n"); //这一行在你不管使用addone 的时候会某明其妙的出现,即使你输入的项目, return 0; //并不存在树中 } new_node=MakeNode(pitem); ptree->size++; if(ptree->root==NULL) ptree->root=new_node; else AddNode(new_node,ptree->root); return 1; } int InTree(const Item *pitem,const Tree *ptree) { return(SeekItem(pitem,ptree).child==NULL?0:1); } int DeleteItem(const Item *pitem,Tree *ptree) { Pair temp; temp=SeekItem(pitem,ptree); if(temp.child==NULL) return 0; else if(temp.parent==NULL) DeleteNode(&ptree->root); else if(temp.parent->left==temp.child) DeleteNode(&temp.parent->left); else DeleteNode(&temp.parent->right); ptree->size--; return 1; } void Traverse(const Tree *ptree,void(*pfun)(Item item)) { if(ptree!=NULL) TraverseTree(ptree->root,pfun); } void DeleteAll(Tree *ptree) { if(ptree->root!=NULL) DeleteAllNode(ptree->root); ptree->root=NULL; ptree->size=0; } static Node *MakeNode(const Item *pitem) { Node * new_node; new_node=(Node *)malloc(sizeof(Node)); if(new_node!=NULL) { new_node->item=*pitem; new_node->left=NULL; new_node->right=NULL; } return new_node; } static int ToLeft(const Item *pitem1,const Item *pitem2) { int flag=strcmp(pitem1->name,pitem2->name) return 1; else return 0; } static int ToRight (const Item *pitem1,const Item*pitem2) { int flag=strcmp(pitem1->name,pitem2->name); if(flag<0) return 1; else return 0; } static void AddNode(Node *new_node,Node *root) { if(ToLeft(&new_node->item,&(root->item))) { if(root->left==NULL) root->left=new_node; else AddNode(new_node,root->left); } else if(ToRight(&new_node->item,&(root->item))) { if(root->right==NULL) root->right=new_node; else AddNode(new_node,root->right);} } static void TraverseTree(const Node *root,void (*pfun)(Item item)) { if(root!=NULL) { TraverseTree(root->left,pfun); (*pfun)(root->item); TraverseTree(root->right,pfun); } } static Pair SeekItem(const Item *pitem,const Tree *ptree) { Pair temp; temp.parent=NULL; temp.child=ptree->root; while(temp.child!=NULL) { if(ToLeft(pitem,&temp.child->item)) { temp.parent=temp.child; temp.child=temp.child->left; } else if (ToRight(pitem,&temp.child->item)) { temp.parent=temp.child; temp.child=temp.child->right; } else break; } return temp; } static void DeleteNode(Node **ptree) { Node * temp; if((*ptree)->left==NULL) { temp=*ptree; *ptree=(*ptree)->right; free(temp); } else if ((*ptree)->right==NULL) { temp=*ptree; *ptree=(*ptree)->left; free(temp); } else { for(temp=(*ptree)->left;temp->right==NULL;temp=temp->right) break; temp->right=(*ptree)->right; temp=*ptree; (*ptree)=(*ptree)->left; free(temp); } } static void DeleteAllNode(Node * root) { Node *pright; if (root!=NULL) { pright=root->right; DeleteAllNode(root->left); free(root); DeleteAllNode(pright); } }