是否可以在不比较键值的情况下将新节点插入二叉树(不是bst)中?以下代码仅适用于前三个节点。
node *insert (node *root, int *key) {
if (root==NULL) {
root=newNode(root, key);
return root;
}
else if (root->left == NULL)
root->left=insert(root->left,key);
else if (root-> right == NULL)
root->right=insert(root->right,key);
return root;
}
答案 0 :(得分:1)
如果您更改
else if (root-> right == NULL)
只是
else
然后它将具有始终添加到右侧的效果。
如果您希望它随机选择,请在此功能之外向srand
添加一个呼叫。
srand(time(NULL));
然后在此函数中,调用
else if (rand() > MAX_RAND / 2) {
root->right = insert(root->right, key);
} else {
root->left = insert(root->left, key);
}
位于现有if
/ else
结构的末尾。
另请参阅:
如果树跟踪每个节点的高度,则可以在进行null检查之后添加
else if (root->left->height <= root->right->height) {
root->left = insert(root->left, key);
} else {
root->right = insert(root->right, key);
}
这将使树自动保持平衡。但它需要其他代码来管理高度。例如。
root->height = 1 + ((root->left->height > root->right->height) ? root->left->height : root->right->height);
这笔额外的开销是否值得,由您自己决定。
建议使用堆的人建议使用索引作为排序。这对于堆来说是没有用的,但是会生成一个平衡的二叉树。因此,根节点将是第一个插入的节点,而最近插入的将是最右边的叶子。
答案 1 :(得分:1)
您可以只跟踪每个节点的高度,并始终将其插入到子节点较少的一侧:
node *insert (node *root, int *key) {
if (root==NULL) {
root=newNode(root, key);
root->height = 0
}
else if (root->left == NULL) {
insert(root->left,key);
}
else if (root->right == NULL) {
insert(root->right,key);
}
else if (root->left->height <= root->right->height) {
insert(root->left,key);
} else {
insert(root->right,key);
}
root->height++
}
答案 2 :(得分:0)
在
else if (root->left == NULL)
root->left=insert(root->left,key);
您知道root->left
为NULL,为什么要进行递归调用?
当然,下一个 else
以下代码仅适用于前三个节点。
如果 left 和 right 都不为NULL,则您不会插入,这时有必要在两个分支之一上进行递归调用,您将考虑密钥(因此请按顺序插入)决定哪个密钥。请注意,如果您插入有排序树,则您对NULL进行的2次测试是不正确的。
答案 3 :(得分:0)
比较值实际上是不相关的,您唯一需要做的就是设置一个指针。由于您没有指定任何实际要求,因此一种解决方案如下:
稍微更改签名,现在您有了一个指向已分配节点的指针:
void insertNode(node *&root, node *newNode) {
if (root == NULL) {
root = newNode;
return;
}
if (root->left == NULL) {
root-left = newNode;
return;
}
helperInsert(root->left, newNode);
return;
}
这将设置头(假设我的签名正确),否则检查左子。
void helperInsert(node *it, node *newNode) {
if (it->left == NULL) {
it->left = newNode;
return;
}
helperInsert(it->left, newNode);
return;
}
这显然是一种有缺陷的方法(几乎不会平衡树),几乎将树视为链接列表,但是据我对问题的最佳理解,这是如何完成此问题的示例。
答案 4 :(得分:0)
堆建议最合理。您无需堆积任何东西,只需遵循索引public class RetriableProcessorExponentialDecorator implements AbsMessageProcessorDecorator {
private final AbsMessageProcessor messageProcessor;
@Autowired
private AbsMessageActiveMQConfiguration configuration;
@Override
public void onMessage(AbsMessage message) throws Exception {
int executionCounter = 0;
int delayCounter = 1000;
final int maxRetries = this.configuration.getExceptionRetry() + 1;
do {
executionCounter++;
try {
this.messageProcessor.onMessage(message);
} catch (RetriableException e) {
log.info("Failed to process message. Retry #{}", executionCounter);
Thread.sleep(delayCounter);
delayCounter = delayCounter * 2;
} catch (Exception e) {
// We don't retry on this, only RetriableException.
throw e;
}
} while (executionCounter < maxRetries && delayCounter < Long.MAX_VALUE);
}
}
上的元素在k
和2*k + 1
上具有子元素的规则。
另一种方法是在没有数组但动态生成节点的情况下有用,它是逐级填充树。请注意,在2*k + 2
级,有k
个时隙,方便地用k位整数索引。将索引解释为沿着树的路径(清除位指示跟随左子节点,置位指示跟随右子节点),沿以下行:
2 ** k