求有调试能力的大神帮下忙,关于二叉树的程序...
这两天,我写了一个二叉树的实现代码,有结点插入和删除,结点遍历输出,返回结点数目等功能,但是写出来修改完错误,却达不到我的预想。还不是擅长调试 - -,求大神解决,可以的话加我QQ 871847544在删除结点和遍历时都会产生崩溃,程序如下:
程序代码:
/*主函数 My_tree.c */ #include <stdio.h> #include <string.h> #include <stdbool.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; bool the_order_iseffective=false; InitializeTree(&classmates); //初始化一棵树 menu(); while(strcmp(gets(yourchoice),"quit")!=0&&yourchoice[0]!='\0') //当输入"quit"或者空行时退出循环 { for(choice=addone;choice<=cleanall;choice++) //与可使用的命令集进行比较, { if(strcmp(yourchoice,choices[choice])==0) { the_order_iseffective=true; 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=false; while(getchar()!='\n') continue; puts("next order\n"); menu(); } 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"); return 0; } 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) //返回结点数目的方法 { unsigned 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",item.name,item.sex,item.age); } /*头文件, tree.h */ #ifndef _TREE_H_ //头文件在这里 #define _TREE_H_ #include <stdbool.h> #define SIZE 15 #define MAXSIZE 15 typedef struct item //构造存储所需项目的数据结构,这是简单的指人的数据结构,并使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; unsigned int size; } Tree; typedef struct pair //构造一种数据结构,便于搜索二叉树中特定的项目,返回指向要搜索结点的指针和指向其父节点的指针, { Node * parent; Node * child; }Pair; void InitializeTree(Tree *ptree); //二叉树的操作集 bool TreeIsEmpty(const Tree *ptree); bool TreeIsFull(const Tree *ptree); unsigned int TreeItemCount(const Tree*ptree); bool AddItem(const Item *pitem,Tree *ptree); bool InTree(const Item *pitem,const Tree *ptree); bool 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 bool ToLeft(const Item *pitem1,const Item *pitem2); static bool 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 **ptree); static void DeleteAllNode(Node *root); void InitializeTree(Tree *ptree) //树的初始化,根节点为空,结点数目为0 { ptree->root=NULL; ptree->size=0; } bool TreeIsEmpty(const Tree *ptree) //判断树是否为空,如果是,返回tree { if(ptree->root==NULL) return true; else return false; } bool TreeIsFull(const Tree *ptree) //判断树是否为满树,如果是,返回tree; { if(ptree->size==MAXSIZE) return true; else return false; } unsigned int TreeItemCount(const Tree *ptree) //返回二叉树中结点数目 { return ptree->size; } bool AddItem(const Item *pitem,Tree *ptree) //在二叉树中添加一个结点 { Node *new_node; if(SeekItem(pitem,ptree).child!=NULL) //判断要添加的结点是否已经存在在树中, { printf("the item is already exist."); return false; } new_node=MakeNode(pitem); //为新的结点分配空间,并创造新的结点 if(new_node==NULL) { printf("FAIED TO CREAT A NODE!"); return false; } ptree->size++; if(ptree->root==NULL) //如果树跟为空,则树根结点=新结点 ptree->root=new_node; else AddNode(new_node,ptree->root); //如果树根不为空,则添加结点 } bool InTree(const Item *pitem,const Tree *ptree) //判断树中是否有该项目 { return(SeekItem(pitem,ptree).child==NULL?false:true); } bool DeleteItem(const Item *pitem,Tree *ptree) //删除树中某个结点 { Pair temp; temp=SeekItem(pitem,ptree); if(temp.child==NULL) return false; else if(temp.parent==NULL) DeleteNode(&ptree->root); else DeleteNode(&temp.child); ptree->size--; return true; } 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 bool ToLeft(const Item *pitem1,const Item *pitem2) //用于比较二叉树中项目该节点应该在左边?如果该,返回真, { //用C语言字符串的比较, int flag; if(flag=strcmp(pitem1->name,pitem2->name)<0) return true; else return false; } static bool ToRight (const Item *pitem1,const Item*pitem2) //同上,比较是否在右边 { int flag; if(flag=strcmp(pitem1->name,pitem2->name)<0) return true; else return false; } 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); } else printf("no member!"); } 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); } }
[ 本帖最后由 那小扎 于 2013-6-12 18:15 编辑 ]