Siwei Xu bdd315b1a7 new solutions of "Populating Next Right Pointers in Each Node"
1) level order traversal by a explicit queue
2) constant space, use `next` pointer to represent the queue
2015-10-26 18:44:33 +08:00

238 lines
5.3 KiB
C++

// Source : https://oj.leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/
// Author : Hao Chen
// Date : 2014-06-19
/**********************************************************************************
*
* Follow up for problem "Populating Next Right Pointers in Each Node".
* What if the given tree could be any binary tree? Would your previous solution still work?
*
* Note:
* You may only use constant extra space.
*
* For example,
* Given the following binary tree,
*
* 1
* / \
* 2 3
* / \ \
* 4 5 7
*
* After calling your function, the tree should look like:
*
* 1 -> NULL
* / \
* 2 -> 3 -> NULL
* / \ \
* 4-> 5 -> 7 -> NULL
*
*
**********************************************************************************/
#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;
/**
* Definition for binary tree with next pointer.
*/
struct TreeLinkNode {
int val;
TreeLinkNode *left, *right, *next;
TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {}
TreeLinkNode() : val(0), left(NULL), right(NULL), next(NULL) {}
};
void connect(TreeLinkNode *root) {
if (root==NULL) return;
if (root->left && root->right){
root->left->next = root->right;
}
if (root->next) {
TreeLinkNode *left=NULL, *right=NULL;
left = root->right ? root->right: root->left;
for (TreeLinkNode *p = root->next; p!=NULL; p=p->next) {
if (p->left){
right = p->left;
break;
}
if (p->right){
right = p->right;
break;
}
}
if (left){
left->next = right;
}
}
connect(root->right);
connect(root->left);
}
void connect1(TreeLinkNode *root) {
if (root==NULL){
return;
}
vector<TreeLinkNode*> v;
v.push_back(root);
while(v.size()>0){
if ( (root->left && root->left->next==NULL) || (root->right && root->right->next==NULL) ) {
if (root->left && root->right){
root->left->next = root->right;
}
if (root->next){
TreeLinkNode *left=NULL, *right=NULL;
left = root->right ? root->right: root->left;
for (TreeLinkNode *p = root->next; p!=NULL; p=p->next) {
if (p->left){
right = p->left;
break;
}
if (p->right){
right = p->right;
break;
}
}
if (left){
left->next = right;
}
}
if (root->left) {
v.push_back(root->left);
}
if (root->right) {
v.push_back(root->right);
}
}
root = v.back();
v.pop_back();
}
}
void connect3(TreeLinkNode *root) {
if(root == NULL) return;
queue<TreeLinkNode*> q;
TreeLinkNode *prev, *last;
prev = last = root;
q.push(root);
while(!q.empty()) {
TreeLinkNode* p = q.front();
q.pop();
prev->next = p;
if(p->left ) q.push(p->left);
if(p->right) q.push(p->right);
if(p == last) { // meets last of current level
// now, q contains all nodes of next level
last = q.back();
p->next = NULL; // cut down.
prev = q.front();
}
else {
prev = p;
}
}
}
// constant space
// key point: we can use `next` pointer to represent
// the buffering queue of level order traversal.
void connect4(TreeLinkNode *root) {
if(root == NULL) return;
TreeLinkNode *head, *tail;
TreeLinkNode *prev, *last;
head = tail = NULL;
prev = last = root;
#define push(p) \
if(head == NULL) { head = tail = p; } \
else { tail->next = p; tail = p; }
push(root);
while(head != NULL) {
TreeLinkNode* p = head;
head = head->next; // pop
prev->next = p;
if(p->left ) push(p->left);
if(p->right) push(p->right);
if(p == last) {
last = tail;
p->next = NULL; // cut down.
prev = head;
}
else {
prev = p;
}
}
#undef push
}
void printTree(TreeLinkNode *root){
if (root == NULL){
return;
}
printf("[%2d] : left[%d], right[%d], next[%d]\n",
root->val,
root->left ? root->left->val : -1,
root->right ? root->right->val : -1,
root->next?root->next->val : -1 );
printTree(root->left);
printTree(root->right);
}
int main()
{
const int cnt = 15;
TreeLinkNode a[cnt];
for(int i=0; i<cnt; i++){
a[i].val = i+1;
}
for(int i=0, pos=0; pos<cnt-1; i++ ){
a[i].left = &a[++pos];
a[i].right = &a[++pos];
}
a[5].left = a[5].right = NULL;
a[3].right = NULL;
//a[1].right = NULL;
//a[2].left = NULL;
//a[3].left = &a[4];
//a[6].right= &a[5];
TreeLinkNode b(100), c(200);
//a[3].left = &b;
//a[6].right = &c;
a[9].left = &b;
connect(&a[0]);
printTree(&a[0]);
return 0;
}