问题:在不创建任何新的节点的情况下,实现将一颗BST变成有序的双向链表。
分析:
在结构上,如图的一颗BST,每个节点都有left right指针分别指指向左右儿子。结构上和双向链表节点是完全相同的。
在有序上,BST中序遍历的结果刚好是我们想要的双向链表的顺序,那么对于一个节点来说,他的left一定指向双向链表当前
最后一个节点。这样完全可以通过保存当前结果的最后一个节点,来实现双向链表的串联。
具体的,我们可以先找到整棵树的最靠左的节点,作为双向链表的起始点,同时也是初始状态的last_node节点。不断处理lastnode与current node之间的关系并更新last node 即可。
// // main.cpp // BSTToList // // Created by LiJinxu on 2017/2/26. // Copyright © 2017年 LiJinxu. All rights reserved. // #include <iostream> #include <cstdio> #include <string> using namespace std; typedef struct TNode { TNode *left, *right; int val; TNode(int v):val(v){} }*pNode; pNode rt; void createBST(pNode p) { string num; while (cin>>num) { p = rt; if(num != "#"){ pNode newNode = new TNode(atoi(num.c_str())); if(p == NULL){ rt = newNode; }else{ int n = atoi(num.c_str()); while (p){ if(n > p -> val){ if(p -> right == NULL){ p -> right = newNode; break; } else p = p -> right; }else{ if(p -> left == NULL){ p -> left = newNode; break; } else p = p -> left; } } } }else{ break; } } } void travelBST(pNode p) { if(p){ travelBST(p -> left); cout<<"node: "<<p->val<<endl; travelBST(p -> right); } } pNode lastNode; pNode lBeginNode; pNode findTheLeftNode(pNode p) { if(p){ if(p -> left == NULL) return p; else return findTheLeftNode(p -> left); } return NULL; } void convert(pNode p) { if (p) { convert(p -> left); if(lastNode != p){ p -> left = lastNode; lastNode -> right = p; lastNode = p; }else{ p -> left = NULL; } convert(p -> right); } } void dispDLink(pNode p){ p = lBeginNode; pNode lEndNode = NULL; cout<<"From left to right: "<<endl; while (p) { cout<<p->val<<" "; if(p -> right == NULL) lEndNode = p; p = p -> right; } cout<<endl<<"end node: "<<lEndNode->val<<endl; p = lEndNode; cout<<"From right to left: "<<endl; while (p) { cout<<p->val<<" "; p = p -> left; } } void solve(pNode rt) { lBeginNode = findTheLeftNode(rt); lastNode = lBeginNode; convert(rt); cout<<"begin node: "<<lBeginNode->val<<endl; dispDLink(lBeginNode); } int main(int argc, const char * argv[]) { createBST(rt); //travelBST(rt); solve(rt); return 0; }