1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
| #include"tree.h" #include<stdio.h> #include<stdlib.h> #include<string.h> struct pair { Trnode* parent; Trnode* child; };
typedef struct pair Pair;
static Pair SeekItem(const Item* pi, const Tree* ptree); static bool ToLeft(const Item* pi1, const Item* pi2); static bool ToRight(const Item* pi1, const Item* pi2); static Trnode* MakeNode(const Item* pi); static void AddNode(Trnode* new_node, Trnode* root); static void DeleteNode(Trnode** pptrn); static void InOrder(Trnode* ptrn, V_FP_ITEM pf); static void DeleteAllNode(Trnode* ptrn); void InitializeTree(Tree* ptree) { ptree->root = NULL; ptree->size = 0; } bool TreeIsEmpty(const Tree* ptree) { return !ptree->root ? true : false; } bool TreeIsFull(const Tree* ptree) { return MAXITEMS == ptree->size ? true : false; } int TreeItemCount(const Tree* ptree) { return ptree->size; } bool AddItem(Item* pi, Tree* ptree) { Trnode* new_node; if (TreeIsFull(ptree)) { fputs("Tree is full.\n", stderr); return false; } if (SeekItem(pi, ptree).child) { fputs("Attempt to add duplicate item.\n", stderr); return false; } if (!(new_node = MakeNode(pi))) { fputs("Can not create dynamic memory.\n", stderr); return false; } ptree->size++; if (!ptree->root) 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 ? true : false; } bool DeleteItem(const Item* pi, Tree* ptree) { Pair look; look = SeekItem(pi, ptree); if (!look.child) return false; if (!look.parent) 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, V_FP_ITEM pf) { if (ptree) InOrder(ptree->root, pf); } void DeleteAll(Tree* ptree) { if (ptree) { DeleteAllNode(ptree->root); ptree->root = NULL; ptree->size = 0; } } static Pair SeekItem(const Item* pi, const Tree* ptree) { Pair look; look.parent = NULL; look.child = ptree->root; if (!look.child) return look; while (look.child) { 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* pi1, const Item* pi2) { int compare; if ((compare = strcmp(pi1->pet_name, pi2->pet_name)) < 0) return true; else if (!compare && strcmp(pi1->pet_kind, pi2->pet_kind) < 0) return true; else return false; }
static bool ToRight(const Item* pi1, const Item* pi2) { int compare; if ((compare = strcmp(pi1->pet_name, pi2->pet_name)) > 0) return true; else if (!compare && strcmp(pi1->pet_kind, pi2->pet_kind) > 0) return true; else return false; } static Trnode* MakeNode(const Item* pi) { Trnode* new_node; if (new_node = (Trnode*)malloc(sizeof(Trnode))) { new_node->item = *pi; new_node->left = new_node->right = NULL; } return new_node; } static void AddNode(Trnode* new_node, Trnode* root) { if (ToLeft(&new_node->item, &root->item)) { if (!root->left) root->left = new_node; else AddNode(new_node, root->left); } else if (ToRight(&new_node->item, &root->item)) { if (!root->right) root->right = new_node; else AddNode(new_node, root->right); } else { fputs("Location error in AddNode().\n", stderr); system("pause"); exit(EXIT_FAILURE); } } static void DeleteNode(Trnode** pptrn) { Trnode* temp; if (!(*pptrn)->left) { temp = *pptrn; *pptrn = (*pptrn)->right; free(temp); } else if (!(*pptrn)->right) { temp = *pptrn; *pptrn = (*pptrn)->left; free(temp); } else { for (temp = (*pptrn)->left; temp->right; temp = temp->right) continue; temp->right = (*pptrn)->right; temp = *pptrn; *pptrn = (*pptrn)->left; free(temp); } } static void InOrder(Trnode* ptrn, V_FP_ITEM pf) if (ptrn) { InOrder(ptrn->left, pf); (*pf)(&ptrn->item); InOrder(ptrn->right, pf); } } static void DeleteAllNode(Trnode* ptrn) { Trnode* pright; if (ptrn) { pright = ptrn->right; DeleteAllNode(ptrn->left); free(ptrn); DeleteAllNode(pright); } }
|