头文件:
#ifndef TREE_H_INCLUDED
#define TREE_H_INCLUDED
#include <stdbool.h>
#define MAXSIZE 20
#define MAXNAME 45
typedef struct
{
char petname[MAXNAME];
char petkind[MAXNAME];
} Item;
typedef struct trnode
{
Item item;
struct trnode *left; //左分支指针
struct trnode *right; //右分支指针
} Trnode;
typedef struct tree
{
int size; //记录树存储的数据
Trnode *root; //指向根的指针
} Tree;
/*函数原型*/
/*操作 : 把树初始化为空 */
void initializerTree(Tree *ptree);
/*操作 : 确定树是否为空 */
bool TreeisEmpty(const Tree *ptree);
/*操作 : 确定树是否已满 */
bool TreeisFull(const Tree *ptree);
/*操作 : 确定树的项数 */
int TreeItemCount(const Tree *ptree);
/*操作 : 在树中添加一个项 */
bool AddItem(const Item *pi,Tree *ptree);
/*操作 : 查找项是否在树中 */
bool InTree(const Item *pi,const Tree *ptree);
/*操作 : 从树中删除一个项 */
bool DeleteItem(const Item *pi,Tree *ptree);
/*操作 : 对树中每一项执行特定函数 */
void Traverse(const Tree *ptree,void (*pfun)(Item item));
/*操作 : 清空树 */
void DeleteAll(Tree *ptree);
#endif // TREE_H_INCLUDED
接口实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree.h"
typedef struct pair
{
Trnode *parent;
Trnode *child;
} Pair;
static Trnode *MakeNode(const Item *pi);
static bool ToLeft(const Item *i1,const Item *i2);
static bool ToRight(const Item *i1,const Item *i2);
static void AddNode(Trnode *pnew,Trnode *root);
static void InOrder(const Trnode *root,void (*pfun)(Item item));
static Pair SeekItem(const Item *pi,const Tree *ptree);
static void DeleteNode(Trnode **ptr); //因为要改变指针的值(指针的指向地址),所以要用指针的指针(指针的地址)
static void DeleteAllNode(Trnode *ptr);
void initializerTree(Tree *ptree)
{
ptree->root=NULL;
ptree->size=0;
}
bool InTree(const Item *pi,const Tree *ptree)
{
if(SeekItem(pi,ptree).child != NULL)
return true;
else
return false;
}
bool TreeisEmpty(const Tree *ptree)
{
if(ptree->root == NULL)
return true;
else
return false;
}
bool TreeisFull(const Tree *ptree)
{
if(ptree->size == MAXSIZE)
return true;
else
return false;
}
int TreeItemCount(const Tree *ptree)
{
return ptree->size;
}
bool AddItem(const Item *pi,Tree *ptree)
{
if(TreeisFull(ptree))
{
fprintf(stderr,"Tree is full!\n");
return false;
}
if(SeekItem(pi,ptree).child != NULL)
{
fprintf(stderr,"Attempted to add duplicate item!\n");
return false;
}
Trnode *pnew;
pnew = MakeNode(pi);
if(pnew == NULL)
{
fprintf(stderr,"Couldn't create node!\n");
return false;
}
if(ptree->root == NULL)
ptree->root = pnew;
else
AddNode(pnew,ptree->root);
ptree->size++;
return true;
}
static Trnode * MakeNode(const Item *pi)
{
Trnode * pnew;
pnew=(Trnode *)malloc(sizeof(Trnode));
if(pnew != NULL)
{
pnew->item = * pi;
pnew->left = NULL;
pnew->right = NULL;
}
return pnew;
}
static Pair SeekItem(const Item * pi,const Tree *ptree)
{
Pair look;
look.parent = NULL;
look.child = ptree->root;
while(look.child != NULL)
{
if(ToLeft(pi,&(look.child->item)))
{
look.parent = look.child;
look.child = look.child->left;
}
else if(ToRight(pi,&(look.child->item)))
{
look.parent = look.child;
look.child = look.child->right;
}
else
break; //相同的情况下
}
return look;
}
static bool ToLeft(const Item * i1,const Item * i2)
{
int i;
if((i = strcmp(i1->petname,i2->petname) ) < 0)
return true;
else if(i == 0 && strcmp(i1->petkind,i2->petkind) < 0)
return true;
else
return false;
}
static bool ToRight(const Item *i1,const Item *i2)
{
int i;
if((i = strcmp(i1->petname,i2->petname))>0)
return true;
else if(i == 0 && strcmp(i1->petkind,i2->petkind)>0)
return true;
else
return false;
}
void Traverse(const Tree * ptree,void (*pfun)(Item item))
{
if(ptree != NULL)
InOrder(ptree->root,pfun);
}
static void InOrder(const Trnode * root,void (*pfun)(Item item))
{
if(root != NULL)
{
InOrder(root->left,pfun);
pfun(root->item);
InOrder(root->right,pfun); //这三条语句可以任意顺序但是这样的顺序是从小到大输出
}
}
static void DeleteAllNode(Trnode *ptr)
{
Trnode * prigtht;
if(ptr != NULL)
{
prigtht = ptr->right;
DeleteAllNode(ptr->left);
free(ptr);
DeleteAllNode(prigtht);
}
/*
也可这样写,更好理解点
Trnode * pleft,* prigtht;
if(ptr != NULL)
{
prigtht = ptr->right;
pleft = ptr->left;
free(ptr);
DeleteAllNode(pleft);
DeleteAllNode(prigtht);
}
*/
}
void DeleteAll(Tree *ptree)
{
if(ptree != NULL)
DeleteAllNode(ptree->root);
ptree->size=0;
ptree->root=NULL;
}
static void AddNode(Trnode * pnew,Trnode * root)
{
if(ToLeft(&pnew->item,&root->item))
{
if(root->left == NULL)
root->left = pnew;
else
AddNode(pnew,root->left);
}
else if(ToRight(&pnew->item,&root->item))
{
if(root->right == NULL)
root->right = pnew;
else
AddNode(pnew,root->right);
}
else
{
fprintf(stderr,"location error in AddNode()!\n");
exit(1);
}
}
bool DeleteItem(const Item * pi,Tree * ptree)
{
Pair look;
look=SeekItem(pi,ptree);
if(look.child == NULL)
return false;
if(look.parent == NULL)
DeleteNode(&ptree->root);
else if(look.parent->left == look.child)
DeleteNode(&look.parent->left);
else if(look.parent->right == look.child)
DeleteNode(&look.parent->right);
ptree->size--;
return true;
}
static void DeleteNode(Trnode **ptr)
{
Trnode * temp;
if((*ptr)->left == NULL)
{
temp=*ptr;
*ptr = (*ptr)->right;
free(temp);
}
else if((*ptr)->right == NULL)
{
temp=*ptr;
*ptr = (*ptr)->left;
free(temp);
}
else
{
for(temp=(*ptr)->left;temp->right!=NULL;temp=temp->right)
continue;
temp->right = (*ptr)->right;
temp = *ptr;
*ptr = (*ptr)->left;
free(temp);
}
}
主函数
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "tree.h"
#include "tree.c"
#include <string.h>
char menu(void);
void addpet(Tree *pt);
void droppet(Tree *pt);
void showpets(const Tree *pt);
void findpet(const Tree *pt);
void uppercase(char *str);
char *s_gets(char *str,int n);
void printitem(Item item);
int main()
{
char ch;
Tree pets;
initializerTree(&pets);
while((ch=menu())!='q')
{
switch(ch)
{
case 'a': addpet(&pets);
break;
case 'l': showpets(&pets);
break;
case 'f': findpet(&pets);
break;
case 'n': printf("%d pets in club\n",TreeItemCount(&pets));
break;
case 'd': droppet(&pets);
break;
default : printf("Switching error\n");
}
puts("========================================================================\n\n");
}
DeleteAll(&pets);
puts("Bye!");
return 0;
}
char *s_gets(char *str,int n)
{
char *pt;
char *find;
pt = fgets(str,n,stdin);
if(pt)
{
find=strchr(str,'\n');
if(find)
*find = '\0';
else
while(getchar()!='\n')
continue;
}
return pt;
}
char menu(void)
{
char ch;
puts("========================================================================");
puts("Nerfville Pet Club Membership Program");
puts("Enter the letter corresponding to your choice:");
puts("a) add a pet l) show list of pets");
puts("n) number of pets f) find pets");
puts("d) delete a pet q) quit");
while((ch=getchar()) != EOF)
{
while(getchar() != '\n')
continue;
ch=tolower(ch);
if(strchr("alnfdq",ch) == NULL)
puts("Please enter an a,l,f,n,d or q:");
else
break;
}
if(ch == EOF)
ch='q';
return ch;
}
void addpet(Tree *pt)
{
Item temp;
if(TreeisFull(pt))
puts("No room in the club!");
else
{
puts("Please enter name of pet:");
s_gets(temp.petname,MAXNAME);
puts("Please enter kind of pet:");
s_gets(temp.petkind,MAXNAME);
uppercase(temp.petkind);
uppercase(temp.petname);
AddItem(&temp,pt);
}
}
void showpets(const Tree *pt)
{
if(TreeisEmpty(pt))
puts("No entries!");
else
Traverse(pt,printitem);
}
void printitem(Item item)
{
printf("Pet: %-19s Kind: %-19s\n",item.petname,item.petkind);
}
void findpet(const Tree *pt)
{
Item temp;
if(TreeisEmpty(pt))
{
puts("No enteries!");
return ;
}
puts("Please enter name of pet you wish to find:");
s_gets(temp.petname,MAXNAME);
puts("Please enter pet kind:");
s_gets(temp.petkind,MAXNAME);
uppercase(temp.petkind);
uppercase(temp.petname);
printf("%s the %s ",temp.petname,temp.petkind);
if(InTree(&temp,pt))
printf("is a number.\n");
else
printf("is not a number.\n");
}
void droppet(Tree *pt)
{
Item temp;
if(TreeisEmpty(pt))
{
puts("No entries!");
return ;
}
puts("Please enter name of pet you wish to deletet:");
s_gets(temp.petname,MAXNAME);
puts("Please enter pet kind:");
s_gets(temp.petkind,MAXNAME);
uppercase(temp.petkind);
uppercase(temp.petname);
printf("%s the %s ",temp.petname,temp.petkind);
if(DeleteItem(&temp,pt))
printf("is dropped from the club.\n");
else
printf("is not a member.\n");
}
void uppercase(char *str)
{
while(*str)
{
*str=toupper(*str);
str++;
}
}