修改后的二叉树,就大仙解惑》》 = =,
我修改后的二叉树,应该可以在任何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);
}
}









