求有调试能力的大神帮下忙,关于二叉树的程序...
这两天,我写了一个二叉树的实现代码,有结点插入和删除,结点遍历输出,返回结点数目等功能,但是写出来修改完错误,却达不到我的预想。还不是擅长调试 - -,求大神解决,可以的话加我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 编辑 ]









