由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
JobHunting版 - 插入节点到complete binary tree的末尾
相关主题
yelp 面经麻烦谁贴一个bug free的BST next node
微软面试的一道题请教linked list, 删除最后一个节点
关于inordertraversal 的iterative way一道在线题
least common ancestor的疑惑请教一道g算法题
问两道facebook面试题FB面经
想到一道老题求教Leetcode题目:Lowest Common Ancestor
mirror 一个binary tree, 用non-recursive解法怎么做两个有点难度很有意思的题
问个google面试题How to find the kth biggest number in a BST
相关话题的讨论汇总
话题: node话题: null话题: root话题: left话题: tmp
进入JobHunting版参与讨论
1 (共1页)
d********w
发帖数: 363
1
complete tree定义
a binary tree in which every level, except possibly the last, is completely
filled, and all nodes are as far left as possible.
不能使用额外的空间,
insert(int data, TreeNode root)
例如complete tree
1
2 3
4
插入节点就是成为2的右儿子
1
2 3
4 5
I*******l
发帖数: 203
2
Update: fix some boundary condition checks
recursively call a function Node* cc(Node* root) to find out where to insert an extra node, where cc checks left subtree first and then right subtree to find a non-full subtree. It returns NULL if both subtrees are full.
Node* cc(Node* root)
{ // make sure that leaf node return NULL
if (root == NULL)
return NULL;
// first check if root has both children, if not return root
if (root->left != NULL && root->right == NULL)
return root;
Node* tmp = cc(root->left);
// left subtree has priority
if (tmp != NULL)
return tmp;
tmp = cc(root->right);
// if right subtree is also full, then return NULL
return tmp ? tmp : NULL;
}
p*****2
发帖数: 21240
3
BFS就可以了。
h****e
发帖数: 928
4
难点是不能使用额外的空间。BFS要用一个队列吧。

【在 p*****2 的大作中提到】
: BFS就可以了。
p*****2
发帖数: 21240
5

sorry. in place呀。

【在 h****e 的大作中提到】
: 难点是不能使用额外的空间。BFS要用一个队列吧。
t**********h
发帖数: 2273
6
有nullpointer的异常。每次调用的时候检查一下,或者第一行先判断root是否为空
很不错的想法。如果已经是完全树,则跑到最左下角节点去insert

insert an extra node, where cc checks left subtree first and then right
subtree to find a non-full subtree. It returns NULL if both subtrees are
full.

【在 I*******l 的大作中提到】
: Update: fix some boundary condition checks
: recursively call a function Node* cc(Node* root) to find out where to insert an extra node, where cc checks left subtree first and then right subtree to find a non-full subtree. It returns NULL if both subtrees are full.
: Node* cc(Node* root)
: { // make sure that leaf node return NULL
: if (root == NULL)
: return NULL;
: // first check if root has both children, if not return root
: if (root->left != NULL && root->right == NULL)
: return root;
: Node* tmp = cc(root->left);

p*****2
发帖数: 21240
7
traverse一下吧。如果都满了就插到最左边的叶子下边。
t**********h
发帖数: 2273
8
后续遍历,同时统计左右子树的节点数目,第一个左右节点数不相同的及是要找的子树根节点。前提
是假定
了这棵树是完整树。
Node result = null;
boolean setResult = true;
int check(Node node){
if(node == null){
return 0;
}

int left = check(node.left);
int right = check(node.right);

if(left != right && setResult){
result = node;
setResult = false;
}

return left + right + 1;
}
补充一下,在check弄完之后,result有两种情况
1.result为空,那么这棵树最底层也被填满,那么下一步找到最左下角叶子插入一个左节点
2.result不为空,那么这棵树最底层没有被填满,那么其倒数二层肯定是被填满的。result就是第
一个左右子树节点数目不同的节点,那么找到result的右子树的最左下角的那个点(要判断
result.right非空,如果空,直接擦),就肯定是要插入的点
j********e
发帖数: 1192
9
写了个使用O(1)memory, O(logN * logN) (N是tree的size)的程序。
类似于binary search的算法,测试代码也在下面,应该没有大bug。
先获得树的高度h,然后比较h和root->right子树的高度+1,如果相同,
说明树最后一个节点在root->right,否则最后一个节点在root->left的子树。
#include
#include
#include
#include
using namespace std;
class Node {
private:
Node *left;
Node *right;
int value;

public:
Node() {
left = right = NULL;
value = 0;
}

Node(int v) {
left = right = NULL;
value = v;
}

int Height(Node *node) {
int h = 0;
if(node == NULL)
return 0;
while(node) {
h++;
node = node->left;
}
return h;
}
int HeightRight(Node *node) {
int h = 0;
if(node == NULL)
return 0;
while(node) {
h++;
node = node->right;
}
return h;
}
bool Insert(Node *root, Node *newNode) {
if(root == NULL)
return false;
int height = Height(root);
int checkLevel = 1;
// First check if last level is full
if(height == HeightRight(root)) {
Node *node = root;
while(node) {
if(node->left == NULL) {
node->left = newNode;
return true;
}
node = node->left;
}
}
Node *lastMoveLeftNode = root;
Node *tmp = root;
while(true) {
if(tmp->right) {
int h = Height(tmp->right) + checkLevel;
if(h == height) {
tmp = tmp->right;
checkLevel ++;
}
else {
lastMoveLeftNode = tmp;
tmp = tmp->left;
checkLevel ++;
}
}
else if(tmp->left) {
// tmp->left is the last node in the complete tree.
tmp->right = newNode;
return true;
}
else {
// tmp is the last node in the complete tree.
// So go back to lastMoveLeftNode to inert newNode
if(!lastMoveLeftNode->right) {
lastMoveLeftNode->right = newNode;
return true;
}
else {
tmp = lastMoveLeftNode->right;
while(tmp->left)
tmp = tmp->left;
tmp->left = newNode;
return true;
}
}
}
return false;
}
void Print() {
list queue;

queue.push_back(this);

while(queue.size()>0) {
Node *node = queue.front();
queue.pop_front();
printf("%d ", node->value);
/*
if(node->left) {
printf("(%d, ", node->left->value);
}
else
printf("(NULL, ");
if(node->right) {
printf("%d) ", node->right->value);
}
else
printf("NULL) ");
*/
if(node->left) {
queue.push_back(node->left);
if(node->right) {
queue.push_back(node->right);
}
}
}
printf("\n\n");
}
};
int main(int argc, char *argv[]) {
int n = 10;

if(argc >= 2) {
n = atoi(argv[1]);
}

Node *root = new Node(0);
for(int i=1; i //printf("\nInsert %d\n", i);
root->Insert(root, new Node(i));
}

root->Print();
return 0;
}

入点。前提是假定

【在 t**********h 的大作中提到】
: 后续遍历,同时统计左右子树的节点数目,第一个左右节点数不相同的及是要找的子树根节点。前提
: 是假定
: 了这棵树是完整树。
: Node result = null;
: boolean setResult = true;
: int check(Node node){
: if(node == null){
: return 0;
: }
:

D********g
发帖数: 650
10
不错的想法,不过这个算法只能handle下面这种case:
1
2 4
3
但是cc对下面的case会return NULL,但是我们希望cc return 4.
1
2 4
3 5

insert an extra node, where cc checks left subtree first and then right
subtree to find a non-full subtree. It returns NULL if both subtrees are
full.

【在 I*******l 的大作中提到】
: Update: fix some boundary condition checks
: recursively call a function Node* cc(Node* root) to find out where to insert an extra node, where cc checks left subtree first and then right subtree to find a non-full subtree. It returns NULL if both subtrees are full.
: Node* cc(Node* root)
: { // make sure that leaf node return NULL
: if (root == NULL)
: return NULL;
: // first check if root has both children, if not return root
: if (root->left != NULL && root->right == NULL)
: return root;
: Node* tmp = cc(root->left);

c*****n
发帖数: 96
11
void getNode (Node *root, int level, int & minLevel, Node *&target){
if (root == NULL) return;
if (root->left == NULL || root->right == NULL){
if (level < minLevel){
target = root;
minLevel = level;
}
}
getNode(root->left, level+1, minLevel, target);
getNode(root->right, level+1, minLevel, target);
}
Node *target = NULL;
getNode(root, 0, INT_MAX, target)
c*****n
发帖数: 96
12
void getNode (Node *root, int level, int & minLevel, Node *&target){
if (root == NULL) return;
if (root->left == NULL || root->right == NULL){
if (level < minLevel){
target = root;
minLevel = level;
}
}
getNode(root->left, level+1, minLevel, target);
getNode(root->right, level+1, minLevel, target);
}
Node *target = NULL;
getNode(root, 0, INT_MAX, target)
t**********h
发帖数: 2273
13
这个算法好长啊,面试的时候能写完吗?

【在 j********e 的大作中提到】
: 写了个使用O(1)memory, O(logN * logN) (N是tree的size)的程序。
: 类似于binary search的算法,测试代码也在下面,应该没有大bug。
: 先获得树的高度h,然后比较h和root->right子树的高度+1,如果相同,
: 说明树最后一个节点在root->right,否则最后一个节点在root->left的子树。
: #include
: #include
: #include
: #include
: using namespace std;
: class Node {

p*****o
发帖数: 1285
14
如果知道节点数,可以直接算出来位置。具体的,先遍历计数,O(n),然后根据总数计
算到下一个节点的路径,可以用位操作很方便算出,然后再O(log n)跑到位置。总的是
O(n + log n)=O(n)。如果已知节点数就是O(log n)。

completely

【在 d********w 的大作中提到】
: complete tree定义
: a binary tree in which every level, except possibly the last, is completely
: filled, and all nodes are as far left as possible.
: 不能使用额外的空间,
: insert(int data, TreeNode root)
: 例如complete tree
: 1
: 2 3
: 4
: 插入节点就是成为2的右儿子

1 (共1页)
进入JobHunting版参与讨论
相关主题
How to find the kth biggest number in a BST问两道facebook面试题
BST 找重复节点数想到一道老题
请教个G题目mirror 一个binary tree, 用non-recursive解法怎么做
recovery BST 不考虑相同值的情况么?问个google面试题
yelp 面经麻烦谁贴一个bug free的BST next node
微软面试的一道题请教linked list, 删除最后一个节点
关于inordertraversal 的iterative way一道在线题
least common ancestor的疑惑请教一道g算法题
相关话题的讨论汇总
话题: node话题: null话题: root话题: left话题: tmp