- 题目描述:
-
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
- 输入:
-
输入可能包含多个测试样例。
对于每个测试案例,输入的第一行为一个数n(0<n<1000),代表测试样例的个数。
接下来的n行,每行为一个二叉搜索树的先序遍历序列,其中左右子树若为空则用0代替。
- 输出:
-
对应每个测试案例,
输出将二叉搜索树转换成排序的双向链表后,从链表头至链表尾的遍历结果。
样例输入:
1 2 1 0 0 3 0 0样例输出:
1 2 3【解题思路】解题的第一步当然是建树,给出先序遍历的二叉搜索树,自然就可以利用树的先序遍历的特点进行建树。先处理当前节点,再递归处理左支与右支。当遇到0则当前节点为空,退出递归。
第二步则是顺序的调整,顺序的调整当然利用二叉搜索树的中序遍历具有的排序功能,对该树进行中序遍历,且在遍历的时候动态的将节点的左右指针值更改掉。且需要维护一个前节点指针pr,将当期节点的pre指针指向pr,pr的next指针指向当期节点,完成双向链接,然后更新pr为当前节点,继续递归。若当前节点为空则退出递归。
当中需要注意的地方就是,内存的申请还是得用c形式的malloc,或者c++形式的new操作,这样便于对指针的处理。
AC code:
#include <iostream> #include <cstdio> #include <string> #include <sstream> #include <vector> #include <iterator> #include <algorithm> using namespace std; struct st { int val; st *pre,*next; }; int cnt=0; void build(st **tre) { int tt; scanf("%d",&tt); if(tt==0) *tre=NULL; else { st *tr=new st(); tr->val=tt; tr->pre=tr->next=NULL; *tre=tr; build(&((*tre)->pre)); build(&((*tre)->next)); } } void convert(st *tre,st**pr) //pr use for recoding the previous node { if(tre==NULL) return; st* snow=tre; if(tre->pre!=NULL) { convert(tre->pre,pr); } snow->pre=*pr; if((*pr)!=NULL) (*pr)->next=snow; *pr=snow; if(tre->next!=NULL) convert(tre->next,pr); } int main() { int n,tt; scanf("%d",&n); getchar(); while(n--) { st *te=NULL; build(&te); //we want get the tre's return value, so we use &tre as parameter,not tre st *pr=NULL; //pr use for recoding the last node convert(te,&pr); while(pr!=NULL && pr->pre!=NULL) pr=pr->pre; while(pr) { printf("%d ",pr->val); pr=pr->next; } printf(" "); } return 0; } /************************************************************** Problem: 1503 User: huo_yao Language: C++ Result: Accepted Time:70 ms Memory:2312 kb ****************************************************************/
题目链接:http://ac.jobdu.com/problem.php?pid=1503九度-剑指Offer习题全套答案下载:http://download.csdn.net/detail/huoyaotl123/8276299