/* 17-8-09-11-21.54.c -- 第十七章第八题 */ /* 17-8-10-17-10.56.c -- 当初决定先去看数据结构回头再弄这东西我觉得是正确的 */ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "17-8-09-11-21.20.h" /* 局部函数声明 */ static Item * Make_Item (const Name_And_Kind * const p_name_and_kind) ; static Node * Make_Node (const Name_And_Kind * const p_name_and_kind) ; static int Left_Is_Greater_Than_Right (const char * const pleft, const char * const pright) ; static int Left_Is_Lesser_Than_Right (const char * const pleft, const char * const pright) ; static int Left_Is_Equal_To_Right (const char * const pleft, const char * const pright) ; static void Print_The_Whole_Item (Item * const pitem, void (* pfun) (const Item * const pitem)) ; static int Seek_Item (const Node * const pnode, const Name_And_Kind * const p_name_and_kind) ; static Node * Delete_Item (Node * const pnode, const Name_And_Kind * const p_name_and_kind) ; static void Copy_Item_To_Node (const Item * const pitem, Node * const pnode) ; /* 接口函数定义 */ void InatializeTree (Tree * const ptree) { *ptree = NULL ; } int TreeIsEmpty (const Tree * const ptree) { return NULL == *ptree ; } int Insert (Tree * const ptree, const Name_And_Kind * const p_name_and_kind) { Node * parent, * scan, * new_node ; Item * new_item, * another_scan ; int index = 0 ; if (TreeIsEmpty (ptree)) { new_node = Make_Node (p_name_and_kind) ; if (NULL == new_node) return 0 ; *ptree = new_node ; return 1 ; } scan = *ptree ; while (scan != NULL) { parent = scan ; if (Left_Is_Greater_Than_Right (p_name_and_kind -> petname, scan -> item -> name_and_kind.petname)) scan = scan -> right ; else if (Left_Is_Lesser_Than_Right (p_name_and_kind -> petname, scan -> item -> name_and_kind.petname)) scan = scan -> left ; /* 遇到重名 */ else { index = ADD_AN_ITEM ; break ; } } /* 要注意这里的ADD_AN_ITEM不能定义成 0 哦! */ if (ADD_AN_ITEM == index) { new_item = Make_Item (p_name_and_kind) ; if (NULL == new_item) return 0 ; another_scan = scan -> item ; while (another_scan -> next != NULL) another_scan = another_scan -> next ; another_scan -> next = new_item ; } else { new_node = Make_Node (p_name_and_kind) ; if (NULL == new_node) return 0 ; if (Left_Is_Greater_Than_Right (p_name_and_kind -> petname, parent -> item -> name_and_kind.petname)) parent -> right = new_node ; else parent -> left = new_node ; } return 1 ; } Node * FindMin (const Tree * const ptree) { if (NULL == *ptree) return NULL ; else if (NULL == (*ptree) -> left) return *ptree ; else return FindMin (&(*ptree) -> left) ; } Node * FindMax (const Tree * const ptree) { Node * scan = *ptree ; if (scan != NULL) while (scan -> right != NULL) scan = scan -> right ; return scan ; } void InorderTraversal (const Tree * const ptree, void (* pfun) (const Item * const pitem)) { if (*ptree != NULL) { InorderTraversal (&(*ptree) -> left, pfun) ; Print_The_Whole_Item ((*ptree) -> item, pfun) ; InorderTraversal (&(*ptree) -> right, pfun) ; } } Tree Delete (Tree * const ptree, Name_And_Kind * p_name_and_kind) { Node * temp ; if (NULL == *ptree) return NULL ; if (Left_Is_Greater_Than_Right (p_name_and_kind -> petname, (*ptree) -> item -> name_and_kind.petname)) (*ptree) -> right = Delete (&(*ptree) -> right, p_name_and_kind) ; else if (Left_Is_Lesser_Than_Right (p_name_and_kind -> petname, (*ptree) -> item -> name_and_kind.petname)) (*ptree) -> left = Delete (&(*ptree) -> left, p_name_and_kind) ; else { /* 如果找到 */ if (Seek_Item (*ptree, p_name_and_kind)) { temp = Delete_Item (*ptree, p_name_and_kind) ; /* 如果使结点为空 */ if (NULL == temp -> item) { if ((*ptree) -> left != NULL && (*ptree) -> right != NULL) { temp = FindMin (&(*ptree) -> right) ; (*ptree) -> item = temp -> item ; (*ptree) -> right = Delete (&(*ptree) -> right, p_name_and_kind) ; } else { temp = *ptree ; if (NULL == (*ptree) -> left) *ptree = (*ptree) -> right ; else *ptree = (*ptree) -> left ; free (temp) ; puts ("----Have Deleted!----") ; } } /* 否则删除工作已经在Delete_Item ()函数完成 */ else *ptree = temp ; } } return *ptree ; } Node * SeekAndReturn (const Tree tree, const Name_And_Kind * const p_name_and_kind) { Node * scan = tree ; while (scan != NULL) { if (Left_Is_Greater_Than_Right (p_name_and_kind -> petname, scan -> item -> name_and_kind.petname)) scan = scan -> right ; else if (Left_Is_Lesser_Than_Right (p_name_and_kind -> petname, scan -> item -> name_and_kind.petname)) scan = scan -> left ; else break ; } return scan ; } /* 局部函数定义 */ static Item * Make_Item (const Name_And_Kind * const p_name_and_kind) { Item * new_item ; new_item = (Item *) malloc (sizeof (Item)) ; if (NULL == new_item) return NULL ; strcpy (new_item -> name_and_kind.petname, p_name_and_kind -> petname) ; strcpy (new_item -> name_and_kind.petkind, p_name_and_kind -> petkind) ; new_item -> next = NULL ; return new_item ; } static Node * Make_Node (const Name_And_Kind * const p_name_and_kind) { Node * new_node ; new_node = (Node *) malloc (sizeof (Node)) ; if (NULL == new_node) return NULL ; new_node -> item = Make_Item (p_name_and_kind) ; if (NULL == new_node -> item) { free (new_node) ; return NULL ; } new_node -> left = NULL ; new_node -> right = NULL ; return new_node ; } static int Left_Is_Greater_Than_Right (const char * const pleft, const char * const pright) { return strcmp (pleft, pright) < 0 ; } static int Left_Is_Lesser_Than_Right (const char * const pleft, const char * const pright) { return strcmp (pleft, pright) > 0 ; } static int Left_Is_Equal_To_Right (const char * const pleft, const char * const pright) { return 0 == strcmp (pleft, pright) ; } static void Print_The_Whole_Item (Item * const pitem, void (* pfun) (const Item * const pitem)) { Item * scan = pitem ; while (scan != NULL) { (* pfun) (scan) ; scan = scan -> next ; } } static int Seek_Item (const Node * const pnode, const Name_And_Kind * const p_name_and_kind) { Item * scan = pnode -> item ; while (scan != NULL) { if (Left_Is_Equal_To_Right (p_name_and_kind -> petkind, scan -> name_and_kind.petkind)) return 1 ; else scan = scan -> next ; } return 0 ; } /* 调用此函数的前提是已经在结点中找到了指定的数据. 如果结点中只有一个Item类型数据, 返回NULL, 即删除后结点为空, 结点也应该被删除 如果结点中有多个Item类型数据, 返回新结点, 完成了删除指定Item类型数据的操作 */ static Node * Delete_Item (Node * const pnode, const Name_And_Kind * const p_name_and_kind) { Item * scan = pnode -> item, * parent = NULL, * temp ; while (scan != NULL) { if (Left_Is_Equal_To_Right (p_name_and_kind -> petkind, scan -> name_and_kind.petkind)) { temp = scan ; if (NULL == parent) pnode -> item = scan -> next ; else parent -> next = scan -> next ; free (temp) ; break ; } else { parent = scan ; scan = scan -> next ; } } return pnode ; } static void Copy_Item_To_Node (const Item * const pitem, Node * const pnode) { strcpy (pnode -> item -> name_and_kind.petname, pitem -> name_and_kind.petname) ; strcpy (pnode -> item -> name_and_kind.petkind, pitem -> name_and_kind.petkind) ; }