宠物清单(二叉查找树实现)

头文件:

#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++;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值