【发布时间】:2020-01-03 11:08:04
【问题描述】:
问题:查找一个节点是在一个节点root的左半子树还是右半子树中。
左半边和右半边的含义:假设一个节点root有n个子节点,每个子节点都有子树。
如果一个节点是从左到右编号为[1..(Math.floor(n/2))] 的节点,或者它是它们的一个子树中的一个节点,则称该节点位于 root 的左半子树中,否则位于 root [(Math.floor(n/2) + 1)..n] 的右半子树中。
左半部分的所有节点的key 值都小于根,而右半部分的所有节点的key 值都大于根。
想法:预处理
对树进行中序遍历并将key(整数)分配给adjacencyLists.node 中的每个节点。然后查询时,比较key的值,判断一个节点是在左半子树还是右半子树:
伪代码:
QUERY(root, queryNode)
if (queryNode.key < root.key) {
print "queryNode is in left half of root"
} else {
print "queryNode is in the right half of root"
}
实施:
var adjacencyLists = {
root: 'A',
nodes: {
A: {
id: 'A',
connectedNodes: ['B', 'C']
},
B: {
id: 'B',
connectedNodes: ['D', 'E']
},
C: {
id: 'C',
connectedNodes: ['F', 'G', 'H', 'Q', 'R']
},
D: {
id: 'D',
connectedNodes: []
},
E: {
id: 'E',
connectedNodes: ['K']
},
F: {
id: 'F',
connectedNodes: ['I']
},
G: {
id: 'G',
connectedNodes: ['J', 'L', 'N', 'P']
},
H: {
id: 'H',
connectedNodes: ['M', 'O']
},
K: {
id: 'K',
connectedNodes: []
},
I: {
id: 'I',
connectedNodes: []
},
J: {
id: 'J',
connectedNodes: []
},
L: {
id: 'L',
connectedNodes: []
},
M: {
id: 'M',
connectedNodes: []
},
N: {
id: 'N',
connectedNodes: []
},
O: {
id: 'O',
connectedNodes: []
},
P: {
id: 'P',
connectedNodes: []
},
Q: {
id: 'Q',
connectedNodes: []
},
R: {
id: 'R',
connectedNodes: []
},
}
}
var keyLookup = {};
var count = 0;
function inorderTraversalNumberingOfNodes(cur) {
if (adjacencyLists.nodes[cur].connectedNodes.length) {
// recurse left half subtrees
for (let i = 0; i < Math.ceil(adjacencyLists.nodes[cur].connectedNodes.length / 2); i++) {
inorderTraversalNumberingOfNodes(adjacencyLists.nodes[cur].connectedNodes[i]);
}
// recurse right half subtrees
for (let i = Math.ceil(adjacencyLists.nodes[cur].connectedNodes.length / 2); i < adjacencyLists.nodes[cur].connectedNodes.length; i++) {
inorderTraversalNumberingOfNodes(adjacencyLists.nodes[cur].connectedNodes[i]);
}
count++;
keyLookup[cur] = { key: count };
} else {
count++;
keyLookup[cur] = {key : count };
}
}
inorderTraversalNumberingOfNodes(adjacencyLists.root);
console.log(keyLookup)
// query to determine whether a node is in the left half or right half of root
function query(rootNodeId, queryNodeId) {
if (keyLookup[queryNodeId].key < keyLookup[rootNodeId].key) {
console.log(`query node ${queryNodeId} is in the left half of root node ${rootNodeId}`);
} else {
console.log(`query node ${queryNodeId} is in the right half of root node ${rootNodeId}`);
}
}
query('A', 'D');
query('M', 'C');
节点的预期键值:邻接表的中序遍历应该为节点分配以下键:
{
"D": {
"key": 1
},
"K": {
"key": 3
},
"E": {
"key": 4
},
"B": {
"key": 2
},
"I": {
"key": 6
},
"F": {
"key": 7
},
"J": {
"key": 8
},
"L": {
"key": 9
},
"N": {
"key": 11
},
"P": {
"key": 12
},
"G": {
"key": 10
},
"M": {
"key": 14
},
"O": {
"key": 16
},
"H": {
"key": 15
},
"Q": {
"key": 17
},
"R": {
"key": 18
},
"C": {
"key": 13
},
"A": {
"key": 5
}
}
现在,在QUERY(A, D) 上,输出应该是queryNode is in left half of root,因为1 < 5。
我没有得到预期的答案,因为我无法将正确的key 分配给节点。
【问题讨论】:
-
问题是什么,上面的结果是什么意思?
-
上述结果是
adjacencyLists中key的期望值,分配给adjacencyLists.node中的每个节点。我做了一些修改,现在清楚了吗? -
我仍然对左右两侧的位置以及数字的含义有疑问。请添加想要的结果。
-
好的,我将编辑问题并添加一些代码 sn-ps
-
顺便说一句,我得到以下顺序:A:5 B:2 D:1 E:4 K:3 C:8 F:7 I:6 G:10 J:9 L:11 N : 12 P: 13 H: 15 M: 14 O: 16 Q: 17 R: 18
标签: javascript node.js algorithm data-structures tree