将二叉搜索树转成要一个排序的双向链表

来源:互联网 发布:手机联系人数据恢复 编辑:程序博客网 时间:2024/05/01 07:04

首先,详细了解下这个问题输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现。

其次,我们要知道在二叉搜索树中,每个结点都有两个分别指向其左、右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值。所以中序便是排序或者说是有序的

思路一:中序遍历的顺序即是我们所要建立链表的顺序。所以可以在中序遍历整棵树的同时,通过调整节点的指针来将其转换为双向链表。当所有结点都访问过之后,整棵树也就转换成一个排序双向链表了。

 思路二:当我们到达某一结点准备调整以该结点为根结点的子树时,先调整其左子树,将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最后链接左子链表的最右结点(左子树的最大结点)、当前结点和右子链表的最左结点(右子树的最小结点)。从树的根结点开始递归调整所有结点。


其实,在看完思路后,读者不禁会想,这跟中序线索化二叉树,好像一样,那我们来看看中序线索化二叉树


(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);}
读者可以将两者比较看看。

0 0
原创粉丝点击