首先,详细了解下这个问题输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现。
其次,我们要知道在二叉搜索树中,每个结点都有两个分别指向其左、右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值。所以中序便是排序或者说是有序的
思路一:中序遍历的顺序即是我们所要建立链表的顺序。所以可以在中序遍历整棵树的同时,通过调整节点的指针来将其转换为双向链表。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了。
思路二:当我们到达某一结点准备调整以该结点为根结点的子树时,先调整其左子树,将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最后链接左子链表的最右结点(左子树的最大结点)、当前结点和右子链表的最左结点(右子树的最小结点)。从树的根结点开始递归调整所有结点。
其实,在看完思路后,读者不禁会想,这跟中序线索化二叉树,好像一样,那我们来看看中序线索化二叉树
(PS:上图是普通二叉树的图,在这里只为讲解)
我们在看看,中序线索化
接下来,我们看其代码
int inorder_threading(bithrtree *thrt, bithrtree bt)
{
*thrt = (bithrtree) malloc (sizeof(bithrnode));
if (!*thrt)
exit(OVERFLOW);
/* 将头结点线索化 */
(*thrt)->ltag = link;
(*thrt)->rtag = thread;
(*thrt)->rchild = (*thrt);
if (!bt) /* 若二叉树为空,则将lchild指向自己 */
(*thrt)->lchild = (*thrt);
else {
(*thrt)->lchild = bt; /* 头结点左指针指向根结点 */
pre = (*thrt);
in_threading(bt); /* 中序遍历进行中序线索化 */
pre->rchild = *thrt;
pre->rtag = thread;
(*thrt)->rchild = pre;
}
return OK;
}
其实,可以看出大同小异,再来看看怎么将二叉搜索树转成要一个排序的双向链表
BinaryTreeNode<T>* Conver()
{
BinaryTreeNode<T>* list = NULL;
ConverNode(_root,list);
BinaryTreeNode<T>* head = list;
while(head && head->_left)
head = head->_left;
return head;
}
void ConverNode(BinaryTreeNode<T>* cur ,BinaryTreeNode<T>*& prv)
{
if(cur == NULL)
return;
BinaryTreeNode<T>* tem = cur;
if(cur->_left)
ConverNode(cur->_left,prv);
tem->_left = prv;
if(prv)
prv->_right = tem;
prv = tem;
if(cur->_right)
ConverNode(cur->_right,prv);
}
读者可以将两者比较看看。