C Primer Plus 收官二叉搜索树实现

先附上编译通过源代码 作为C Primer Plus 总结

tree.h

#ifndef _TREE_H_
#define _TREE_H_
#include <stdbool.h>
typedef struct item{
char petname[20];
char petkind[20];
} Item;
#define MAXITMES 10

typedef struct node
{
  Item item;
  struct node * left;
  struct node * right;
} Node;

typedef struct tree
{
 Node * root;
 int size;
} Tree;

void InitializeTree (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.c

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "tree.h"

typedef struct pair {
    Node * parent;
    Node * child;
} Pair;

static Node * 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 (Node * new_node,Node * root);
static void InOrder (const Node * root,void (* pfun)(Item item));
static Pair SeekItem (const Item * pi,const Tree * ptree);
static void DeleteNode (Node **ptr);
static void DeleteAllNodes (Node *ptr);
void InitializeTree (Tree * ptree){
ptree->root = NULL;
ptree->size =0;

}

bool TreeIsEmpty (const Tree * ptree){
if(ptree->root == NULL)
  return true;
else
 return false;

}

bool TreeIsFull (const Tree * ptree){
if(ptree->size == MAXITMES)
  return true;
else
 return false;

}

int TreeItemCount (const Tree * ptree){
 return ptree->size;

}
bool AddItem (const Item * pi,Tree * ptree){
Node * new_node;
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;
}
new_node = MakeNode(pi);
if(new_node == NULL)
{
 fprintf(stderr,"Couldn't create node \n");
 return false;

}
ptree->size++;

if(ptree->root == NULL)
 ptree->root = new_node;
else
 AddNode(new_node,ptree->root);
return true;
}

bool InTree(const Item *pi,const Tree * ptree){
 return (SeekItem(pi,ptree).child == NULL)?false:true;

}

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
  DeleteNode(&look.parent->right);
 ptree->size--;
 return true;
}

void Traverse(const Tree * ptree,void (* pfun)(Item item))
{
 if(ptree != NULL)
  InOrder(ptree->root,pfun);
}

void DeleteAll (Tree * ptree){
 if(ptree != NULL)
  DeleteAllNodes(ptree->root);
ptree->root = NULL;
ptree->size = 0;
}

static void InOrder(const Node * root,void (* pfun)(Item item))
{
 if(root != NULL)
 {
  InOrder(root->left,pfun);
  (*pfun)(root->item);
  InOrder(root->right,pfun);
 }


}
static void DeleteAllNodes(Node * root)
{
 Node * pright;
if(root != NULL)
{
pright = root->right;
DeleteAllNodes(root->left);
free(root);
DeleteAllNodes(pright);
}

}

static Pair SeekItem (const Item * pi,const Tree * ptree){
 Pair look;
 look.parent = NULL;
 look.child = ptree->root;
 if(look.child == NULL)
     return look;
  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 comp1;
 if((comp1 = strcmp (i1->petname,i2->petname)) < 0){
  return true;  
 }else if(comp1 == 0 && strcmp(i1->petkind,i2->petkind) < 0)
   return true;
 else 
   return false;
}

static bool ToRight (const Item *i1,const Item *i2){
 int comp1;
 if((comp1 = strcmp (i1->petname,i2->petname)) > 0){
  return true;
 }else if(comp1 == 0 && strcmp(i1->petkind,i2->petkind) > 0)
   return true;
 else
   return false;
}

static Node * MakeNode (const Item *pi){
Node * new_node;
new_node = (Node *) malloc(sizeof(Node));
if(new_node != NULL){
 new_node->item = *pi;
 new_node->left = NULL;
 new_node->right = NULL;

}
return new_node;

}
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);

}
else
{

fprintf(stderr,"location error in AddNode() \n");
exit(1);

}
}

static void DeleteNode(Node* *ptr){
 Node * temp;
 puts((*ptr)->item.petname);
 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);

}
}

petclub.c

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include  "tree.h"

char menu(void);
void addpet(Tree * pt);
void droppet(Tree * pt);
void showpets(const Tree *pt);
void findpet(const Tree *pt);
void printitem(Item item);
void uppercase(char * str);

int main(void){
Tree pets;
char choice;
InitializeTree(&pets);
while((choice = menu())!='q')
{
 switch (choice)
 {
  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 : puts("Switching error");
  

 }
}

DeleteAll(&pets);
puts("Bye.");
return 0;
}
char menu (void)
{
 int ch;
 puts("nerfvill pet club membership progarm");
 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("alrfndq",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: ");
 gets(temp.petname);
 puts("Please enter pet kind :");
 gets(temp.petkind);
 uppercase(temp.petname);
 uppercase(temp.petkind);
 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 entries!");
 return;
}
puts("please enter name of pet you wish to find :");
gets(temp.petname);
puts("please enter pet kind :");
gets(temp.petkind);
uppercase(temp.petname);
uppercase(temp.petkind);
printf("%s the %s ",temp.petname,temp.petkind);
if(InTree(&temp,pt))
  printf("is a member.\n");
else
 printf("is not a member.\n");
}

void droppet(Tree * pt)
{
Item temp;
if(TreeIsEmpty(pt))
{
 puts("No entries!");
 return;
}
puts("please enter name of pet you wish to find :");
gets(temp.petname);
puts("please enter pet kind :");
gets(temp.petkind);
uppercase(temp.petname);
uppercase(temp.petkind);
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++;
}

}

 多个文件编译方式 

gcc tree.h tree.c petclub.c -o main

或者Makeflie

main: petclub.o tree.o
  gcc petclub.o tree.o -o main
petclub.o: petclub.c tree.c
  gcc -c petclub.c
tree.o: tree.c tree.h
  gcc -c tree.c

转载于:https://www.cnblogs.com/loongqiang/p/3751464.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值