Objective-C中的二进制树
我正在学习算法和数据结构,并训练我正在使用
objective-c来设计和实现二叉树.
到目前为止,我有以下课程: >主要 – 用于测试 我实现的BinaryTree类中的第一种方法之一是insertNode:forRoot :. - (void)insertNodeByRef:(Node **)node forRoot:(Node **)root{ if (head == NULL) { head = *node; } // Case 2 root is null so can assign the value of the node to it if (root == NULL) { root = node; } else { if (node.data > root.data) { // to the right [self insertNode:node forRoot:root.right]; } else if (node.data < root.data) { //or to the left [self insertNode:node forRoot:root.left]; } } } Node类的接口如下所示: @interface Node : NSObject @property(nonatomic,assign) int data; @property(nonatomic,strong) Node * right; @property(nonatomic,strong) Node * left; @end 我的问题是,如果我传递Node作为参考,我不知道如何访问Node类成员变量.每当我尝试访问节点属性(如数据,左或右)时,我收到以下错误消息: Member reference base type 'Node *__autoreleasing *' is not a structure or union 所以我的问题是: 希望是有道理的.谢谢! 解决方法
你的代码正在混合两个常见的方法来解决这个问题.您也使用抽象数据类型(ADT)类型方法,而不是面向对象的方法,因此有三种方法可以考虑.
在这两个ADT方法中,您的树都以对其根的引用表示,在Objective-C中,这可能存储在一个实例变量中: Node *TreeRoot; 还要注意,这两种算法都使用字段引用a-> b而不是属性引用a.b – 这是因为前者引用了变量,第二种算法需要传递对变量的引用. 功能ADT:传递值并分配结果 在这种方法中,将节点插入到树中,并且返回被修改的树,例如.插入节点NodeToInsert的顶级调用将是: TreeRoot = insertNode(nodeToInsert,TreeRoot); 并且insertNode函数看起来像: Node *insertNode(Node *node,Node *root) { if(root == nil) { // empty tree - return the insert node return node; } else { // non-empty tree,insert into left or right subtree if(node->data > root->data) // to the right { root->right = insertNode(node,root->right); } else if(node->data < root->data)//or to the left { root->left = insertNode(node,root->left); } // tree modified if needed,return the root return root; } } 请注意,在这种方法中,在非空(子)树的情况下,算法对变量执行冗余分配 – 分配的值是已经在变量中的…因为这样,有些人更喜欢: 程序性ADT:通过参考 在这种方法中,保存(子)树的根的变量是通过引用传递的,而不是被传递的值,并且根据需要被调用的过程修改.例如.顶级电话将是: insertNode(nodeToInsert,&TreeRoot); // & -> pass the variable,not its value 并且insertNode过程如下所示: void insertNode(Node *node,Node **root) { if(*root == nil) { // empty tree - insert node *root = node; } else { // non-empty tree,insert into left or right subtree Node *rootNode = *root; if(node->data > rootNode->data) // to the right { insertNode(node,&rootNode->right); } else if(node->data < rootNode->data)//or to the left { insertNode(node,&root->left); } } } 您现在可以看到,您的方法是上述两种方法的混合体.两者都是有效的,但是正如您使用Objective-C一样,最好采用第三种方法: 面向对象的ADT 这是程序ADT的一个变体 – 而不是将变量传递给一个过程,变量(现在称为对象)拥有一个更新自身的方法.这样做意味着您必须在进行呼叫插入节点之前测试一个空(子)树,而前两种方法在调用中进行测试.所以现在我们在Node中有这个方法: - (void) insert:(Node *)node { if(node.data > self.data) // using properties,could also use fields -> { if(self.right != nil) [self.right insert:node]; else self.right = node; } else if(node.data < rootNode.data) { if(self.left != nil) [self.left insert:node]; else self.left = node; } } 您还需要更改顶级调用以对空树执行相同的测试: if(TreeRoot != nil) [TreeRoot insert:nodeToInsert]; else TreeRoot = nodeToInsert; 最后一个注释 – 如果您使用MRC而不是ARC或GC进行内存管理,则需要插入适当的保留/释放调用. 希望能帮助你整理事情. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |