[英]How can I create a recursive binary tree with a bit sequence given by a given preorder traversal?
我遇到麻煩的問題是這個。
每個節點由兩個比特x1和x2表示。 如果節點有左子節點,則x1為1.如果不是,則x1為0.類似於右子節點的情況,x2可以是1或0.使用此規則,我們可以表示位序列下的二叉樹由前序遍歷形成。 例如,從“11010011001000”,我們可以構造以下樹。 編寫一個遞歸函數,該函數可以采用由前序遍歷給出的某個位序列並構造二叉樹。
現在,我一直在從一個類似的問題中獲取信息, 給出了預訂遍歷的構造樹 ,但它看起來如此不同,因為在這種情況下你必須考慮單個節點的x1和x2 ......我一直在我想這幾個小時,但我無法用遞歸得出一個好的邏輯。 任何幫助,將不勝感激。 謝謝!
在達到50聲望之前,我將這個聲明放在我答案的第一行:
我想在評論中做一個簡短的回復,但我沒有足夠的聲譽所以我正在做出完整的答案,希望我的錯誤答案仍然有用。
DFS非常適合這項任務 - 這基本上是預訂遍歷所做的:
def DFS(node):
if(node == NULL) return
sequence += notNull(node.l)
sequence += notNull(node.r)
DFS(node.l)
DFS(node.r)
^^^這就是你的序列的構造方式。
幸運的是反過來很直接:
def inverseDFS(node):
if(node == NULL) return
node.l = new Node() if(readBuffer(sequence) == '1') else NULL
node.r = new Node() if(readBuffer(sequence) == '1') else NULL
inverseDFS(node.l)
inverseDFS(node.r)
^^^僅修改第2行和第3行,現在不是通過子項的存在來確定序列的下一個字符,而是基於下一個字符讀取來確定子項的存在,因為這是iff關系。
這是一個更復雜的C ++代碼,是的,我知道我的編碼風格可能令其他人厭惡。
/* Author haleyk10198 */
/* FOR ACM-ICPC WF*/
#include <bits/stdc++.h>
using namespace std;
struct Node{
static int nodeCnt;
int id;
Node *l, *r;
Node(){
l = r = nullptr;
this->id = nodeCnt++;
}
friend ostream& operator<<(ostream&, const Node);
}*root = new Node();
ostream& operator<<(ostream &out, const Node node){
cout << "Node id: " << node.id
<< " | left child is " << (node.l? node.l->id: -1)
<< " | right child is " << (node.r? node.r->id: -1) << endl;
}
int Node::nodeCnt, strStreamPos = 0;
string str;
void dfs(Node *node){
if(not node)
return;
if(str[strStreamPos++] == '1')
node->l = new Node();
if(str[strStreamPos++] == '1')
node->r = new Node();
cout << *node << endl;
dfs(node->l);
dfs(node->r);
}
int main(){
cin >> str;
dfs(root);
return 0;
}
一個解決方案可能只是遍歷你的樹在preorder
從序列讀取同時(兩個值,並刪除它們),並添加node
,其中是必要的。
鑒於你有這個Node
:
class Node {
int value;
public Node left;
public Node right;
}
你可以像這樣創建一個樹:
private static void createTree(Node root) {
if(string.isEmpty() || root == null) {
return;
}
if(string.charAt(0) == '1') {
root.left = new Node();
}
if(string.charAt(1) == '1') {
root.right = new Node();
}
string = string.substring(2);
createTree(root.left);
createTree(root.right);
}
其中string只是一個全局變量: static String string = "11010011001000";
您可以像這樣調用方法:
Node root = new Node();
createTree(root);
root
將是樹的實際根。
您的問題看起來像這樣: http : //www.geeksforgeeks.org/construct-a-special-tree-from-given-preorder-traversal/
我稍微修改了給定的代碼以滿足您的具體要求。 我忽略了你問題中節點(字母)的給定順序,只關注樹的結構。 時間復雜度是預期的O(N)
。 一切似乎都很清楚所以我沒有提供進一步的信息。 如果您有任何疑問,請隨時發表評論。
public class BinaryTree {
class Node {
char data;
Node left, right;
Node(char item) {
data = item;
left = right = null;
}
}
class Index {
int index = 0;
}
Node root;
Index i = new Index();
Node constructTreeUtil(String bitSequence, Index index_ptr, int n, Node temp) {
int index = index_ptr.index;
String bits = bitSequence.substring(index * 2, index * 2 + 2);
if (index == n)
return null;
temp = new Node((char) (index + 65));
(index_ptr.index)++;
if (bits.charAt(0) == '1')
temp.left = constructTreeUtil(bitSequence, index_ptr, n, temp.left);
if (bits.charAt(1) == '1')
temp.right = constructTreeUtil(bitSequence, index_ptr, n, temp.right);
return temp;
}
Node constructTree(String bitSequence, int n, Node node) {
int index = 0;
return constructTreeUtil(bitSequence, i, n, node);
}
public static void inorder(Node node) {
if (node == null) return;
System.out.println(node.data + "=> ");
if (node.left != null)
System.out.println("Left node: " + node.left.data);
if (node.right != null)
System.out.println("Right node: " + node.right.data);
System.out.println();
inorder(node.left);
inorder(node.right);
}
public static void main(String args[]) {
BinaryTree tree = new BinaryTree();
// Bit sequence
String bitSequence = "11010011001000";
// Number of nodes
int n = bitSequence.length() / 2;
// Tree construction
Node node = tree.constructTree(bitSequence, n, tree.root);
// Print tree nodes inorder
inorder(node);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.