部分转载自http://blog.csdn.net/sgbfblog/article/details/7939589
题目描述
给定一棵二叉排序树(BST),将该树转换成一棵双向循环链表。请看下面的图示说明,你可以更清楚的了解题意。
BST的结构定义如下:
struct node { int data;
node* left;
node* right; }; typedef struct node Node;
图1)一棵存储1-5的二叉搜索树(BST)
图2)根据上面的BST转换得到的有序循环链表。其中,树的左右孩子指针替换成了pre和next指针,分别指向链表的前一个和后一个结点。
c++的代码如下:
#include <iostream> struct TreeNode { int val; TreeNode * left; TreeNode * right; TreeNode(int x) :val(x), left(NULL), right(NULL) {} }; using namespace std; TreeNode * treeToDoublyList(TreeNode * root); void treeToDoublyList(TreeNode ** p, TreeNode ** pre, TreeNode ** head); int main() { TreeNode * root = new TreeNode(5); TreeNode * layer1_node1 = new TreeNode(3); TreeNode * layer1_node2 = new TreeNode(7); TreeNode * layer2_node1 = new TreeNode(1); TreeNode * layer2_node2 = new TreeNode(4); TreeNode * layer2_node3 = new TreeNode(9); root->left = layer1_node1; root->right = layer1_node2; layer1_node1->left = layer2_node1; layer1_node1->right = layer2_node2; layer1_node2->right = layer2_node3; TreeNode * temp = treeToDoublyList(root); TreeNode * head = temp; while (temp->right != head) { cout << temp->val << endl; temp = temp->right; } cout << temp->val << endl; cout << "Hello world!" << endl; //system("pause"); return 0; } TreeNode * treeToDoublyList(TreeNode * root) { TreeNode * head = NULL; TreeNode * pre = NULL; treeToDoublyList(&root, &pre, &head); //cout << "fun 2 over! head value: " << head->val << endl; return head; } void treeToDoublyList(TreeNode ** p, TreeNode ** pre, TreeNode ** head) { if (!(*p)) return; treeToDoublyList(&((*p)->left), pre, head); (*p)->left = *pre; if (*pre) { //cout << (*pre)->val << endl; (*pre)->right = *p; } else *head = *p; TreeNode * r = (*p)->right; (*p)->right = *head; (*head)->left = *p; *pre = *p; treeToDoublyList(&r, pre, head); }
原博主的代码粗略看上去和我的代码没什么区别,但是其实不然,我在自己实现的时候第一个版本的代码也是如原博主的代码一样,但是很不幸出了bug,经过debug我发现问题出在函数调用过程中,C++默认进行传值,而java中非基本类型默认船引用!所以看了《进军硅谷》的书中用java实现的代码,自己再用c++实现,很容易掉入这个坑!所以要注意C++和java的区别,java底层其实用指针实现,对于非基本数据类型,默认传引用,这使得java的代码看上去比c++的代码清晰简洁,至少不需要C++的二重指针,而且减少了错误的发生。但是为了这种看上去的简洁,java的在效率上的牺牲也是巨大的。