剑指 Offer 36. 二叉搜索树与双向链表
思路
方法一: 保存中序遍历的结果,然后依次处理,这里使用vector保存中序遍历结果
1 /* 2 // Definition for a Node. 3 class Node { 4 public: 5 int val; 6 Node* left; 7 Node* right; 8 9 Node() {} 10 11 Node(int _val) { 12 val = _val; 13 left = NULL; 14 right = NULL; 15 } 16 17 Node(int _val, Node* _left, Node* _right) { 18 val = _val; 19 left = _left; 20 right = _right; 21 } 22 }; 23 */ 24 class Solution { 25 private: 26 vector<Node*> v; 27 public: 28 Node* treeToDoublyList(Node* root) { 29 if(root == NULL) 30 return NULL; 31 inorderTraverse(root); 32 33 Node* head = v[0]; 34 Node* p = head; 35 for(int i = 1; i < v.size(); i++) { 36 p->right = v[i]; 37 v[i]->left = p; 38 p = p->right; 39 } 40 41 //首尾互指 42 p->right = head; 43 head->left = p; 44 45 return head; 46 } 47 48 //中序遍历 49 void inorderTraverse(Node* root) { 50 if(root == NULL) 51 return; 52 inorderTraverse(root->left); 53 v.push_back(root); 54 inorderTraverse(root->right); 55 } 56 };
方法二:在中序遍历过程中处理每个结点(就地转换)
需要保存第一个和最后一个结点,
遍历过程中需要知道前一个结点。
1 /* 2 // Definition for a Node. 3 class Node { 4 public: 5 int val; 6 Node* left; 7 Node* right; 8 9 Node() {} 10 11 Node(int _val) { 12 val = _val; 13 left = NULL; 14 right = NULL; 15 } 16 17 Node(int _val, Node* _left, Node* _right) { 18 val = _val; 19 left = _left; 20 right = _right; 21 } 22 }; 23 */ 24 class Solution { 25 private: 26 Node* head = NULL; 27 Node* pre = NULL; 28 public: 29 Node* treeToDoublyList(Node* root) { 30 if(root == NULL) 31 return NULL; 32 33 inorderTraverse(root); 34 //首尾互指 35 head->left = pre; 36 pre->right = head; 37 38 return head; 39 } 40 41 //中序遍历 42 void inorderTraverse(Node* root) { 43 if(root == NULL) 44 return; 45 46 inorderTraverse(root->left); 47 48 //找到头结点 49 if(head == NULL) 50 head = root; 51 //当前和前一个结点pre相互指向对方,构成双向链表 52 if(pre != NULL) { 53 pre->right = root; 54 root->left = pre; 55 } 56 pre = root; //将前一个结点更新为当前结点 57 58 inorderTraverse(root->right); 59 } 60 };