您的位置:首页 > 其它

二叉树插入算法的非递归版本

2016-09-29 19:53 225 查看
首先约定结点和元素类型的的定义:

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
ElementType Data;
BinTree Left;
BinTree Right;
};


对于二叉树的插入算法,从原理上理解是很简单自然的:我们首先需要考虑的是树是空树该怎么办,这是问题的起点。因此,当树是空的,那么当前插入的值就是根结点的元素值。肯定不能直接把元素直接丢在那里,需要用结点的标准形式封装起来。即:

if(BST == NULL) // 是一棵空树的时候,插入的结点就是根结点
{
Position node = (Position)malloc(sizeof(struct TNode));
node->Left = NULL;
node->Right = NULL;
node->Data = X; //标准的初始化结点语句
BST = node; //根结点指向这个新建的结点
return BST; //老实返回去即可
}


如果一般情况下,树中已经有部分结点了,我们知道,二叉树的左结点小于根,根结点小于右边的结点,这是一个递归的性质。因此,想插入一个新的结点,即需要不断和其他结点比较。这个其他结点具体指代什么呢?首先,进来是和根结点比,如果比根结点小,那么就往左走,再和根节点的左子树的根节点比较,假如此时比左子树的根结点值小,不是说就直接插到它的左边结点,为什么呢?因为左子树的左结点可能不是空的啊!因为比左子树的根结点小,所以还是得往左边走。如果恰好左子树的左边没有结点,那就OK,加入到这个位置。

往右边走也是相似的道理。

下面是完整代码:

// 函数Insert将X插入二叉搜索树BST并返回结果树的根结点指针;
BinTree Insert( BinTree BST, ElementType X ) //循环版本的插入算法
{
if(BST == NULL) // 是一棵空树的时候,插入的结点就是根结点
{
Position node = (Position)malloc(sizeof(struct TNode));
node->Left = NULL;
node->Right = NULL;
node->Data = X;

BST = node;
return BST;
}
else
{
Position node = BST;
while(1)
{
if(X == node->Data)
{
return NULL; //错误,退出
}
if(X < node->Data)
{
if(node->Left != NULL)
{
node = node->Left;
}
else
{
Position temp = (Position)malloc(sizeof(struct TNode));
temp->Left = NULL;
temp->Right = NULL;
temp->Data = X;

node->Left = temp;
return BST;
}
}
else
{
if(node->Right != NULL)
{
node = node->Right;
}
else
{
Position temp = (Position)malloc(sizeof(struct TNode));
temp->Left = NULL;
temp->Right = NULL;
temp->Data = X;

node->Right = temp;
return BST;
}
}
}
}
}


但是这种插入操作,问题本身是递归的,最简洁的是用递归算法,但是递归算法虽然简单,但是需要更多的理解才能大胆的用起来。

这次只讨论非递归的算法实现。

以上。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息