[英]C - Binary Search Tree
我在現有的存儲寵物的名稱和種類的二叉樹中實現功能時特別困惑,首先要做的是:
聲明[tree.h]:
typedef struct item
{
char petname[20];
char petkind[20];
} Item;
#define MAXITEMS 10
typedef struct node
{
Item item;
struct node * left; /* pointer to right branch */
struct node * right; /* pointer to left branch */
} Node;
typedef struct tree
{
Node * root; /* pointer to root of tree */
int size; /* number of items in tree */
} 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);
添加節點的功能:
typedef struct pair {
Node * parent;
Node * child;
} Pair;
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;
}
static void AddNode(Node * new_node, Node * root)
{
if((strcmp(new_node->item.petname, root->item.petname))==0)
{
if(root->same==NULL)
root->same=new_node;
else
AddNode(new_node, root->same);
}
else
{
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 bool ToLeft(const Item * i1, const Item * i2)
{
int comp;
if((comp=strcmp(i1->petname,i2->petname))<0)
return true;
else if(comp==0)
return true;
else
return false;
}
static bool ToRight(const Item * i1, const Item * i2)
{
int comp;
if((comp=strcmp(i1->petname,i2->petname))>0)
return true;
else if(comp==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;
new_node->same=NULL;
}
return new_node;
}
(如果您需要更多的代碼,因為有更多的功能,我將其發布)主要的困惑是如何將所有具有相同名稱(不同種類)的寵物添加到同一節點內的列表中,然后通過鍵入取回自己的寵物
原始任務: 修改Pet Club程序,以便將所有具有相同名稱的寵物存儲在同一節點的列表中。 當用戶選擇尋找寵物時,程序應請求寵物名稱,然后列出所有具有該名稱的寵物(及其種類)。
書中的建議:*
對於另一個可能的變化,請考慮Nerfville寵物俱樂部。 該示例按名稱和種類對樹進行排序,因此可以在一個節點中容納貓Sam,在另一個節點中容納狗Sam,在第三個節點中容納山羊Sam。 但是,您不能有兩只叫Sam的貓。 另一種方法是僅按名稱對樹進行排序。 單獨進行更改將只允許一個Sam,無論種類如何,但是您可以將Item定義為結構列表,而不是單個結構。 第一次出現Sally時,程序將創建一個新節點,然后創建一個新列表,然后將Sally及其同類添加到列表中。 出現的下一個Sally將被定向到同一節點並添加到列表中。
*
您應該已經了解鏈接列表。 將這些知識與此處的樹結合起來。 將Item移到鏈接列表,並使Node直接存儲列表而不是Item。
typedef struct itemlistElement
{
Item item;
struct itemlistElement* nextItem; /* pointer to next item on list */
} ItemlistElement;
typedef struct node
{
ItemlistElement* listOfItems; /* pointer to first element of a linked list of Item */
struct node * left; /* pointer to right branch */
struct node * right; /* pointer to left branch */
} Node;
您可以找出其余部分-每次遍歷一棵樹時,都需要執行遍歷列表的額外步驟。 添加項目時,有兩種可能性:添加具有一個項目的新節點,或者將項目添加到現有節點中。 那就是你的書所說的:
(...)然后可以將Item定義為結構列表,而不是單個結構。 第一次出現Sally時,程序將創建一個新節點,然后創建一個新列表,然后將Sally及其同類添加到列表中。 出現的下一個Sally將被定向到同一節點並添加到列表中。
首先:創建列表並使其生效。 首先在單獨的ItemlistElement*
上進行ItemlistElement*
(在樹的外部,您甚至可以在另一個程序中進行列表和列表遍歷功能)。 然后,修改程序以將Item
存儲在列表中,但始終使用一個元素列表。 這應該很容易。 最后一步是將它們結合在一起。 這是最少編碼的步驟,但最具挑戰性。 在輸入之前,請進行所有思考。 當兩個項目仍在工作時(樹和鏈表),請為其制作副本,以防萬一您感到困惑並且程序過於混亂。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.