簡體   English   中英

C-二進制搜索樹

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM