假设我有一个二元搜索树,其中我应该按照标准输入中给定的顺序插入N个唯一编号的键,然后我要删除所有键间隔为I=[最小,最大]的节点,以及与这些节点相邻的所有连接。这给了我很多较小的树,我要以一种特殊的方式将它们合并在一起。更精确地描述问题:
给定包含不同键的BST和间隔I,间隔删除分两个阶段进行。在第一阶段,它将删除关键帧位于I中的所有节点以及与已删除节点相邻的所有边。让生成的图包含k个连通分量T1,。。。,Tk。每个组件都是一个BST,其中根是原始BST中该组件所有节点中深度最小的节点。我们假设树序列Ti被排序,以便对于每个i
编辑:我还应该删除连接节点的任何边,这些边由给定的间隔分隔,这意味着在示例2中连接节点10和20的边被删除,因为间隔[13,15]是“在它们之间”,因此将它们分开。
对于树的空序列,Merge()给出一个空BST。对于包含树T的单元素序列,Merge(T)=T。对于树的序列T1,。。。,Tk,其中k
完成此操作后,我的任务是找到生成的合并树的深度D和深度D-1中的节点数。即使对于100000个节点的树,我的程序也应该在几秒钟内完成(第4个示例)。
我的问题是我不知道如何做到这一点,甚至不知道从哪里开始。我设法在删除之前构建了所需的树,但仅此而已。如果能实现一个程序来解决这个问题或任何建议,我将不胜感激。最好是用某种C语言编程的。
示例:
输入(第一个数字是要插入空树中的键数,第二个是要按给定顺序插入的唯一键,第三行包含两个数字,表示要删除的间隔):
13
10 5 8 6 9 7 20 15 22 13 17 16 18
8 16
程序的正确输出:3 3
,第一个数字是深度D,深度D-1的第二个节点数
输入:
13
10 5 8 6 9 7 20 15 22 13 17 16 18
13 15
正确输出:<代码>4 3
两个示例的图片
示例3:https://justpaste.it/1du6l正确输出:<代码>13 6
示例4:链接正确输出:<代码>58 9
这是一个重要的答案,我将在高层进行讨论。请检查来源以了解详细信息,或询问评论以获得澄清。
全局变量:
功能:
现在代码(不要惊慌!!!):
#include <bits/stdc++.h>
using namespace std;
int N = 12;
struct Node
{
Node* parent=NULL,*left=NULL,*right = NULL;
int value;
Node(int x,Node* par=NULL) {value = x;parent = par;}
};
void insert(Node* root,int x){
if(x<root->value){
if(root->left) insert(root->left,x);
else root->left = new Node(x,root);
}
else{
if(root->right) insert(root->right,x);
else root->right = new Node(x,root);
}
}
int inorder(Node* root){
if(root==NULL) return 0;
int l = inorder(root->left);
return l+1+inorder(root->right);
}
vector<Node*> roots;
map<Node*,int> smap;
vector<int> prefix;
Node* delInterval(Node* root,int x,int y){
if(root==NULL) return NULL;
root->left = delInterval(root->left,x,y);
root->right = delInterval(root->right,x,y);
if(root->value<=y && root->value>=x){
if(root->left) roots.push_back(root->left);
if(root->right) roots.push_back(root->right);
return NULL;
}
if(root->value<x && root->right && root->right->value>y) {
roots.push_back(root->right);
root->right = NULL;
}
if(root->value>y && root->left && root->left->value<x) {
roots.push_back(root->left);
root->left = NULL;
}
return root;
}
Node* merge(int start,int end){
if(start>end) return NULL;
if(start==end) return roots[start];
int total = prefix[end] - (start>0?prefix[start-1]:0);//make sure u get this line
int mid = (total+1)/2 + (start>0?prefix[start-1]:0); //or this won't make sense
int ind = lower_bound(prefix.begin(),prefix.end(),mid) - prefix.begin();
Node* root = roots[ind];
Node* TL = merge(start,ind-1);
Node* TR = merge(ind+1,end);
Node* temp = root;
while(temp->left) temp = temp->left;
temp->left = TL;
temp = root;
while(temp->right) temp = temp->right;
temp->right = TR;
return root;
}
void traverse(Node* root,int depth,map<int, int>& level){
if(!root) return;
level[depth]++;
traverse(root->left,depth+1,level);
traverse(root->right,depth+1,level);
}
int main(){
srand(time(NULL));
cin>>N;
int* arr = new int[N],start,end;
for(int i=0;i<N;i++) cin>>arr[i];
cin>>start>>end;
Node* tree = new Node(arr[0]); //Building initial tree
for(int i=1;i<N;i++) {insert(tree,arr[i]);}
Node* x = delInterval(tree,start,end); //deleting the interval
if(x) roots.push_back(x);
//sort the disconnected roots, and find their size
sort(roots.begin(),roots.end(),[](Node* r,Node* v){return r->value<v->value;});
for(auto& r:roots) {smap[r] = inorder(r);}
prefix.resize(roots.size()); //prefix sum root sizes, to cheaply find 'root' in merge
prefix[0] = smap[roots[0]];
for(int i=1;i<roots.size();i++) prefix[i]= smap[roots[i]]+prefix[i-1];
Node* root = merge(0,roots.size()-1); //merge all trees
map<int, int> level; //key=depth, value = no of nodes in depth
traverse(root,0,level); //find number of nodes in each depth
int depth = level.rbegin()->first; //access last element's key i.e total depth
int at_depth_1 = level[depth-1]; //no of nodes before
cout<<depth<<" "<<at_depth_1<<endl; //hoorray
return 0;
}
当我通过GPS移除一个节点时,当我试图打印二叉树时,会出现堆栈溢出。下面是我的一些代码。我不能理解它将如何工作良好,如果我删除的名称,但不是,如果我删除的坐标,因为我正在使用相同的删除方法。 我得到的确切错误是“Exe:0xC00000FD中0x013214D6处的未处理异常:堆栈溢出(参数:0x00000001,0x00152FFC)”。在按坐标删除后,在打印函数中会出现这种情况,但如果按名称删
点击后即可选中要素,在被点中后高亮的要素中点击所要删除的节点即可完成删除。
本文向大家介绍Javascript removeChild()删除节点及删除子节点的方法,包括了Javascript removeChild()删除节点及删除子节点的方法的使用技巧和注意事项,需要的朋友参考一下 下面给大家介绍Javascript removeChild()删除节点的方法,具体详情如下所示: 在Javascript中,只提供了一种删除节点的方法:removeChild()。 rem
在本章中,我们将学习XML DOM删除节点的操作。删除节点操作是指从文档中删除指定的节点。实现此操作以移除诸如文本节点,元素节点或属性节点之类的节点。 以下是用于删除节点操作的方法 - 方法 方法 1. removeChild()方法 方法从子列表中删除指示的子节点,并将其返回。 删除子节点等同于删除文本节点。 因此,删除子节点会删除与其关联的文本节点。 语法 使用方法的语法如下 - 其中, -
我的问题是,如果用户输入一个姓氏,并且在链接列表中有多个相同的姓氏,并且其中一个姓氏在head节点中。如何在不删除头部节点的情况下删除另一个姓氏。我尝试了一些我能想到的方法,但是删除了所需的节点(这很好),包括头部节点(这不是我想要的…)
输入: 如何删除列顺序中没有值的记录? 期望输出: 我当前的XSL只删除空节点 我似乎无法掌握模板匹配来删除整个“记录”标签。。。非常感谢你!