Problem:
在二叉树中找到一个节点的后继节点
【题目】 现在有一种新的二叉树节点类型如下:
public class Node {
public int value;
public Node left;
public Node right;
public Node parent;
public Node(int data) { this.value = data; }
}
该结构比普通二叉树节点结构多了一个指向父节点的parent指针。
假设有一 棵Node类型的节点组成的二叉树,
树中每个节点的parent指针都正确地指向自己的父节点,
头节点的parent指向null。只给一个在二叉树中的某个节点 node,
请实现返回node的后继节点的函数。在二叉树的中序遍历的序列中,
node的下一个节点叫作node的后继节
Solution:
在中序遍历的顺序中,每一个节点的后一个节点即为该节点的后继节点,
先驱节点即为中序顺序的前面节点。
节点x的后继节点为:
【若有右子树】即为该节点的右子树最左的节点
【若无右子树】:
通过前驱指针,向上回溯父节点,并判断该节点是否为该父节点的左子树,
若是,则该父节点为该节点的后继节点。不是,父节点继续向上回溯其父。
若一直找不到,则该节点的后继节点为空。
Code:
1 #pragma once 2 #include <iostream> 3 #include <vector> 4 #include <queue> 5 6 using namespace std; 7 8 struct Node 9 { 10 int val; 11 Node* lchild; 12 Node* rchild; 13 Node* parent; 14 Node(int a = -1) :val(a), lchild(NULL), rchild(NULL),parent(NULL) {} 15 }; 16 17 void Create(Node*& root, vector<int>num)//层序构造树 18 { 19 queue<Node*>q; 20 root = new Node(num[0]); 21 q.push(root); 22 int i = 1; 23 while (i < num.size() && !q.empty()) 24 { 25 Node* p = q.front(); 26 q.pop(); 27 if (!p)//空节点p 28 break; 29 if (num[i] > 0) 30 { 31 p->lchild = new Node(num[i++]); 32 p->lchild->parent = p; 33 } 34 if (num[i] > 0) 35 { 36 p->rchild = new Node(num[i++]); 37 p->rchild->parent = p; 38 } 39 q.push(p->lchild); 40 q.push(p->rchild); 41 } 42 } 43 44 void MidTravel(Node *root) 45 { 46 if (!root) 47 return; 48 MidTravel(root->lchild); 49 cout << root->val << " "; 50 MidTravel(root->rchild); 51 } 52 53 Node* FindNode(Node* node) 54 { 55 if (node->rchild)//有右子树,那么后继节点即为右子树的最左的节点 56 { 57 Node* p = node->rchild; 58 while (p->lchild) 59 p = p->lchild; 60 return p; 61 } 62 //无右子树 63 //后继节点为该节点为某个父节点的左子树 64 Node *f;//父亲指针 65 f = node->parent; 66 while (!f) 67 { 68 if (node == f->lchild) 69 return f; 70 node = f; 71 f = node->parent; 72 } 73 return NULL; 74 } 75 76 void Test() 77 { 78 Node* root = NULL; 79 vector<int>num = { 1,2,3,4,5,6,7,8,9,10,11,12,-1,-1,-1 }; 80 Create(root, num);//层序构造树 81 82 cout << "=============查看中序遍历==============" << endl; 83 MidTravel(root); 84 cout << endl << endl; 85 86 Node* p = NULL; 87 p = root->rchild; 88 cout << "节点 " << p->val << " 的后继节点为:"; 89 p = FindNode(p); 90 if (p) 91 cout << p->val << endl; 92 else 93 cout << "空。" << endl; 94 95 p = root->lchild->rchild; 96 cout << "节点 " << p->val << " 的后继节点为:"; 97 p = FindNode(p); 98 if (p) 99 cout << p->val << endl; 100 else 101 cout << "空。" << endl; 102 103 p = root->rchild->rchild; 104 cout << "节点 " << p->val << " 的后继节点为:"; 105 p = FindNode(p); 106 if (p) 107 cout << p->val << endl; 108 else 109 cout << "空。" << endl; 110 111 } 112