【问题标题】:Preorder Binary Search Tree Insertion前序二叉搜索树插入
【发布时间】:2012-12-17 23:23:05
【问题描述】:

一个非常愚蠢的问题,我几乎不好意思问。我一直在搜索过去 4 小时,测试了不同的算法,在纸上尝试了很多,但仍然无法使其正常工作。

我不会向您详细介绍项目实施的细节,但基本问题是:“您如何处理在预购二叉树中插入节点。

通过 Pre-Order BST,我的意思是所有节点都应该以这样一种方式插入,即使用 pre-order traversal 遍历树(例如用于打印)应该按升序打印节点。

我只需要一个简单的算法。我尝试了这里给出的简单插入算法(在stackoverflow上,但似乎不正确(也在纸上尝试过));。

节点基本上是这样的:

typedef struct testNode{
    int key;
    struct testNode *leftChild;
    struct testNode *rightChild;
}NODE;

插入数据只是一个唯一整数列表。我创建一个以 int 为键的节点,然后应该将该节点添加到树中。我有根节点,它以 NULL 指针开始。

抱歉,如果有什么不清楚的地方。

感谢您的帮助!

编辑:根据下面提供的算法,这是我想出的:

void insert(NODE **tree,int key){
if(*tree){
    if ((*tree)->key >= key){
        //Insert before this .....
        NODE *temp = createNode(key);
        temp->lc = (*tree);
        (*tree) = temp;

    }
    else if(!(*tree)->rc){
        //Right Child doesn't exist ....
        insert(&(*tree)->lc,key);
    }
    else if((*tree)->rc->key < key){
        //Right child exists and is smaller than spread ... insert left ...
        insert(&(*tree)->lc,key);
    }
    else{
        //Right child exists and is greater than spread ... insert right ...
        insert(&(*tree)->rc,key);
    }
    //If the code as progressed to this point, insertion must have occured, 
            //and the code returns ......   
} else {
    //the **tree pointer points to NULL. Insert here ....
    SPREADNODE *temp = createSpreadNode(spread);
    //temp->lc = (*tree);
    (*tree) = temp;
}
}

【问题讨论】:

  • 我希望你刚刚粘贴了错误的结构。
  • 当您说“预排序”二叉树时,您是指 BST(已经排序)还是与预排序遍历有关?
  • 是的,这个结构是匆忙输入的,我会编辑它。预排序,从某种意义上说,我应该在树中插入节点,以便在使用预排序遍历遍历它时,它会以正确的顺序访问节点。
  • 不会编译。节点不能包含自身的实例。 sizeof (struct testNode) 是什么?大小(结构测试节点)? 2* sizeof(testNode) + sizeof(int) ?
  • @wildplasser,你必须原谅我,我已经在这里待了将近 5 个小时。 leftChild 和 rightChild 实际上是指针。

标签: c binary-search-tree insertion preorder


【解决方案1】:

考虑预排序 BST 的定义:根节点是最小的元素,它的两个子节点或也是预排序树,使得右子树的根大于左子树中的任何值。

因此,一种可行的算法是:

  1. 如果新节点小于根节点,则将其设为新根节点并指向现有树作为两个子节点之一。
  2. 如果新节点大于根,但小于右子树的根,递归插入左子树。
  3. 否则,递归插入右子树。

这不太可能产生一个非常平衡的树,但它应该可以工作。我至少可以想到一个其他简单的替代方案,毫无疑问,有一些方法可以让事情变得更加平衡,我将其作为练习留给读者;-)

【讨论】:

  • 感谢您的回答,我将立即开始实施:)。同时,让我评论一下: 1. 我已经通过插入整数的降序(即 5 4 3 2 1)尝试了这一点。它基本上通过左子指针创建一个链表。 2. 我想到了这个。如果一个节点小于右子树的根,那么根据定义,它应该小于左子树的根。为什么在左子树之前插入优先于右子树插入?
  • 另外,很抱歉把问题弄得一团糟:基本上我到目前为止所做的是使用预订遍历树,当我到达 >= 节点(或 NULL)插入在那个位置之前。我应该如何进行插入?我是否应该检查所有“特殊”情况(例如,在右孩子之前插入,左兄弟为 NULL?在右孩子和它的父母之间插入不能比在左孩子插入更好的平衡树,可以吗?
  • 我建议你睡一觉。另外:不要触摸您的计算机。首先用铅笔和纸画一些图画。如果递归定义问题,只需要两个条件,IICC。结果很简单:要么替换根节点(“下推”),要么替换 L 或 R 子树,和/或递归。在你触摸键盘之前画出来!
  • 当你开始递归思考时;丢失的子节点与空的根节点没有什么不同。 (在这两种情况下,“下推”一个 NULL 节点/指针都不会造成任何伤害)
  • @GCon:在我看来,前序树插入比有序插入更难,因为您不会仅通过检查当前节点来了解有关递归的所有信息;我可能是错的,但在我看来,为了做出正确的递归选择而对孩子进行检查是不可避免的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-17
相关资源
最近更新 更多