先附上编译通过源代码 作为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