tree.h
#ifndef _TREE_H_ #define _TREE_H_ #include#define SLEN 20 #define MAXITEMS 10 typedef struct item { char petname[SLEN]; char petkind[SLEN]; } Item; typedef struct trnode { Item item; struct trnode* left; struct trnode* right; } Trnode; typedef struct tree { Trnode* root; int size; } Tree; void InitializeTree(Tree* ptree); bool TreeIsEmpty(const Tree* ptree); bool TreeIsFull(const Tree* ptree); int TreeIremCount(const Tree* ptree); bool AddItem(const Item* ip, 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.cpp
#include#include #include #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* new_node, 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 DeleteAllNodes(Trnode* 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 == MAXITEMS) return true; else return false; } int TreeIremCount(const Tree* ptree) { return ptree->size; } bool AddItem(const Item* pi, Tree* ptree) { Trnode* new_node; if (TreeIsFull(ptree)) { fprintf(stderr, "树以满!n"); return false; } if (SeekItem(pi, ptree).child != NULL) { fprintf(stderr, "添加重复项目!n"); return false; } new_node = MakeNode(pi); //指向新节点 if (new_node == NULL) { fprintf(stderr, "不能创建节点!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 Trnode* MakeNode(const Item* pi) { Trnode* new_node; new_node = (Trnode*)malloc(sizeof(Trnode)); if (new_node != NULL) { new_node->item = *pi; new_node->left = NULL; new_node->right = NULL; } return new_node; } 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 void AddNode(Trnode* new_node, Trnode* 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, "没有添加节点的位置!"); exit(1); } } 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 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 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); } } static void DeleteAllNodes(Trnode* root) { Trnode* pright; if (root != NULL) { pright = root->right; DeleteAllNodes(root->left); free(root); DeleteAllNodes(pright); } }
use.cpp
#include#include #include #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); char* s_gets(char* st, int n); 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 clubn", TreeIremCount(&pets)); break; case 'd': droppet(&pets); break; default: puts("输入错误!"); } } DeleteAll(&pets); puts("退出!"); return 0; } char menu(void) { int ch; puts("输入选择:"); puts("a: 添加宠物 l: 罗列所以宠物"); puts("n: 宠物数量 f: 寻找宠物"); puts("d: 删除宠物 q: 退出"); while ((ch = getchar()) != EOF) { while (getchar() != 'n') continue; ch = tolower(ch); if (strchr("alrfndq", ch) == NULL) puts("输入:a, l, f, n, d, q"); else break; } if (ch == EOF) ch = 'q'; return ch; } void addpet(Tree* pt) { Item temp{}; if (TreeIsFull(pt)) puts("无成员!"); else { puts("输入宠物名字:"); s_gets(temp.petname, SLEN); puts("输入宠物种类:"); s_gets(temp.petkind, SLEN); uppercase(temp.petname); uppercase(temp.petkind); AddItem(&temp, pt); } } void droppet(Tree* pt) { Item temp; if (TreeIsEmpty(pt)) { puts("无成员!"); return; } puts("输入删除的名称:"); s_gets(temp.petname, SLEN); puts("输入删除的种类:"); s_gets(temp.petkind, SLEN); uppercase(temp.petname); uppercase(temp.petkind); printf("%s the %s ", temp.petname, temp.petkind); if (DeleteItem(&temp, pt)) printf("is dorpped from the club.n"); else printf("is not a number.n"); } void showpets(const Tree* pt) { if (TreeIsEmpty(pt)) puts("无成员!"); else Traverse(pt, printitem); } void findpet(const Tree* pt) { Item temp{}; if (TreeIsEmpty(pt)) { puts("无成员!"); return; } puts("输入查找宠物的名字:"); s_gets(temp.petname, SLEN); puts("输入查找宠物的种类:"); s_gets(temp.petkind, SLEN); uppercase(temp.petname); uppercase(temp.petkind); printf("%s the %s ", temp.petname, temp.petkind); if (InTree(&temp, pt)) printf("是成员!n"); else printf("不是成员!n"); } void printitem(Item item) { printf("Pet: %-19s Kind: %-19sn", item.petname, item.petkind); } void uppercase(char* str) { while (*str) { *str = toupper(*str); str++; } } char* s_gets(char* st, int n) { char* ret_val = nullptr; char* find = nullptr; ret_val = fgets(st, n, stdin); if (ret_val) { find = strchr(st, 'n'); if (find) *find = ' '; else while (getchar() != 'n') continue; } return ret_val; }



