繁体   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