题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
比如将二元查找树
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
//================================================================================
原想直接中序遍历然后建立一个双链表的,可是要求不能建新节点...
当然有一点啥时候都错不了的就是:递归
由于在网上查到的代码都太难懂了,所以我觉得自己重写一遍。
//================================================================================
思路一:当我们到达某一结点准备调整以该结点为根结点的子树时,先调整其左子树将左子树转换成一个排好序的左子链表,再调整其右子树转换右子链表。最近链接左子链表的最右结点(左子树的最大结点)、当前结点和右子链表的最左结点(右子树的最小结点)。从树的根结点开始递归调整所有结点。
//------------------------------------
//========后序遍历
//==注意一定是后序遍历,这样才能从子节点向父节点移动,否则父节点的指针一调整指向就找不到子树了
template<class T>
void BST<T>::inorder (BSTNode *p){
if(p!=0){
inorder(p->left );
inorder(p->right );
visit(p);
}
}
//------------------------------------
//=======重点在于这个visit函数
void visit(BSTNode *p){//由上面的遍历的代码可以看到p是一个非叶节点
//把tmp1指向P的左子树,循环右移找出最右节点,然后我们将它设为的P的前驱节点。
tmp1=p->left;
while(tmp1 != NULL){tmp1=tmp1->right;}
p->left=tmp;
//tmp2同理
tmp2=p->right;
while(tmp2 != NULL){tmp2=tmp2->left;}
p->left=tmp;
}
//================================================================================
思路二:ing