使用二叉搜索树查找重复项
Using binary search tree to find duplicates
我实现了二叉搜索树。我的代码很简单。
struct Tree{
Tree* left;
Tree* right;
int value;
};
在这里我声明了基本结构。
Tree* makenode(int val){
Tree* tmp= new Tree;
tmp->left=tmp->right=NULL;
tmp->value=val;
return tmp;
}
创建另一个结构类型树的函数。
void setLeft(Tree* x,int val){
x->left=makenode(val);
}
void setRight(Tree* x,int val){
x->right=makenode(val);
}
void insertt(Tree *x,int val){
while(1){
if(val < x->value){
if(x->left!=NULL){
x=x->left;
}else{
setLeft(x,val);
break;
}
}else{
if(x->right!=NULL){
x=x->right;
}else{
setRight(x,val);
break;
}
}
}
}
遍历树并在正确的位置插入值 = 在添加到树的同时对树进行排序。
给我添麻烦的就是这个小功能
void travel(Tree *x){
if(x->left!=NULL){
travel(x->left);
}
Tree *b;
b=x->right;
if(x->value == b->value){
cout << "Duplicate is " << x->value << endl;
return ;
}
cout << "Value is " << x->value << endl;
if(x->right!=NULL){
travel(x->right);
}
}
如果我省略
,它会很好地打印值
Tree *b;
b=x->right;
if(x->value == b->value){
cout << "Duplicate is " << x->value << endl;
return ;
}
我希望它在打印当前值时检查 enxt 值,它们是相同的 = 我们有口是心非。但它总是使我的程序崩溃。是什么原因造成的?排序有效,唯一可能出现的问题是递归行为,但我不知道是什么
我试着把它改成
void travel(Tree *x, vector<int> &y){
vector<int>::iterator it;
if(x->left!=NULL){
if( x->value == x -> left -> value){
it=find( y.begin(), y.end(), x->value );
if(it==y.end()){
y.push_back(x->value);
}
}
travel(x->left, y);
}
cout << "Value is " << x->value << endl;
if(x->right!=NULL){
if( x->value == x -> right -> value){
it=find( y.begin(), y.end(), x->value );
if(it==y.end()){
y.push_back(x->value);
}
}
travel(x->right,y);
}
}
但是有了这个主要功能
int main()
{
vector<int> dups;
Tree * node = makenode(55);
insertt(node,99);
insertt(node,5);
insertt(node,99);
insertt(node,100);
insertt(node,13);
insertt(node,99);
insertt(node,55);
travel(node,dups);
printDup(dups);
return 0;
}
and printDup
使用命名空间标准;
void printDup( vector<int> &y){
cout << "Duplicates are: ";
for( int i = 0; i < y.size(); i++){
cout << y[i] << " ";
}
}
它只打印 99 ,为什么其他值没有被推入向量?另外我怎样才能使旅行功能更优雅?
It only prints 99 , why doesnt the others values get pushed into vector?
插入值 55、99、5、99、100、13、99、55 后,您的树如下所示:
55
/ \
/ \
/ \
5 99
\ / \
13 55 99
\
100
/
99
所以您查找重复项的算法只识别 99,因为您只检查节点的子节点是否具有与节点自身相同的 value
。
注意子树中节点的后继是其右子节点的外层左节点,而前任节点是其左子节点的外层右节点。
像这样调整您的代码并使用std::set
存储重复项:
#include <set>
int outerleft( Tree *x )
{
while ( x->left != nullptr ) x = x->left;
return x->value;
}
int outerright( Tree *x )
{
while ( x->right != nullptr ) x = x->right;
return x->value;
}
void travel(Tree *x, std::set<int> &dups )
{
if ( x->left != nullptr )
{
if ( x->value == outerright( x->left ) )
dups.insert( x->value );
travel( x->left, dups );
}
std::cout << "Value is " << x->value << std::endl;
if ( x->right != nullptr )
{
if ( x->value == outerleft( x->right ) )
dups.insert( x->value );
travel( x->right, dups );
}
}
void printDup( const std::set<int> &dups )
{
std::cout << "Duplicates are: ";
for( int v : dups )
std::cout << v << " ";
}
Python代码
import json
class Node:
def __init__(self, val=0):
self.right = ''
self.left = ''
self.value = val
class Tree(Node):
def addNode(self, tree, node, duplicates):
if not tree:
tree = node
elif tree.value > node.value:
if tree.left:
tree.left = self.addNode(tree.left, node, duplicates)
else:
tree.left = node
elif tree.value < node.value:
if tree.right:
tree.right = self.addNode(tree.right, node, duplicates)
else:
tree.right = node
elif tree.value == node.value:
duplicates.append(node.value)
return tree
def buildTree():
arr = [14, 15, 4, 9, 7, 18, 3, 5, 16, 20,4,17, 9, 14, 5]
tree = Tree()
duplicates = []
for v in arr:
node = Node(v)
tree = tree.addNode(tree, node, duplicates)
s = json.dumps(tree.__dict__, default=serialize)
print(s)
print(duplicates)
def serialize(obj):
return obj.__dict__
if __name__ == '__main__':
buildTree()
我实现了二叉搜索树。我的代码很简单。
struct Tree{
Tree* left;
Tree* right;
int value;
};
在这里我声明了基本结构。
Tree* makenode(int val){
Tree* tmp= new Tree;
tmp->left=tmp->right=NULL;
tmp->value=val;
return tmp;
}
创建另一个结构类型树的函数。
void setLeft(Tree* x,int val){
x->left=makenode(val);
}
void setRight(Tree* x,int val){
x->right=makenode(val);
}
void insertt(Tree *x,int val){
while(1){
if(val < x->value){
if(x->left!=NULL){
x=x->left;
}else{
setLeft(x,val);
break;
}
}else{
if(x->right!=NULL){
x=x->right;
}else{
setRight(x,val);
break;
}
}
}
}
遍历树并在正确的位置插入值 = 在添加到树的同时对树进行排序。
给我添麻烦的就是这个小功能
void travel(Tree *x){
if(x->left!=NULL){
travel(x->left);
}
Tree *b;
b=x->right;
if(x->value == b->value){
cout << "Duplicate is " << x->value << endl;
return ;
}
cout << "Value is " << x->value << endl;
if(x->right!=NULL){
travel(x->right);
}
}
如果我省略
,它会很好地打印值Tree *b;
b=x->right;
if(x->value == b->value){
cout << "Duplicate is " << x->value << endl;
return ;
}
我希望它在打印当前值时检查 enxt 值,它们是相同的 = 我们有口是心非。但它总是使我的程序崩溃。是什么原因造成的?排序有效,唯一可能出现的问题是递归行为,但我不知道是什么
我试着把它改成
void travel(Tree *x, vector<int> &y){
vector<int>::iterator it;
if(x->left!=NULL){
if( x->value == x -> left -> value){
it=find( y.begin(), y.end(), x->value );
if(it==y.end()){
y.push_back(x->value);
}
}
travel(x->left, y);
}
cout << "Value is " << x->value << endl;
if(x->right!=NULL){
if( x->value == x -> right -> value){
it=find( y.begin(), y.end(), x->value );
if(it==y.end()){
y.push_back(x->value);
}
}
travel(x->right,y);
}
}
但是有了这个主要功能
int main()
{
vector<int> dups;
Tree * node = makenode(55);
insertt(node,99);
insertt(node,5);
insertt(node,99);
insertt(node,100);
insertt(node,13);
insertt(node,99);
insertt(node,55);
travel(node,dups);
printDup(dups);
return 0;
}
and printDup
使用命名空间标准;
void printDup( vector<int> &y){
cout << "Duplicates are: ";
for( int i = 0; i < y.size(); i++){
cout << y[i] << " ";
}
}
它只打印 99 ,为什么其他值没有被推入向量?另外我怎样才能使旅行功能更优雅?
It only prints 99 , why doesnt the others values get pushed into vector?
插入值 55、99、5、99、100、13、99、55 后,您的树如下所示:
55
/ \
/ \
/ \
5 99
\ / \
13 55 99
\
100
/
99
所以您查找重复项的算法只识别 99,因为您只检查节点的子节点是否具有与节点自身相同的 value
。
注意子树中节点的后继是其右子节点的外层左节点,而前任节点是其左子节点的外层右节点。
像这样调整您的代码并使用std::set
存储重复项:
#include <set>
int outerleft( Tree *x )
{
while ( x->left != nullptr ) x = x->left;
return x->value;
}
int outerright( Tree *x )
{
while ( x->right != nullptr ) x = x->right;
return x->value;
}
void travel(Tree *x, std::set<int> &dups )
{
if ( x->left != nullptr )
{
if ( x->value == outerright( x->left ) )
dups.insert( x->value );
travel( x->left, dups );
}
std::cout << "Value is " << x->value << std::endl;
if ( x->right != nullptr )
{
if ( x->value == outerleft( x->right ) )
dups.insert( x->value );
travel( x->right, dups );
}
}
void printDup( const std::set<int> &dups )
{
std::cout << "Duplicates are: ";
for( int v : dups )
std::cout << v << " ";
}
Python代码
import json
class Node:
def __init__(self, val=0):
self.right = ''
self.left = ''
self.value = val
class Tree(Node):
def addNode(self, tree, node, duplicates):
if not tree:
tree = node
elif tree.value > node.value:
if tree.left:
tree.left = self.addNode(tree.left, node, duplicates)
else:
tree.left = node
elif tree.value < node.value:
if tree.right:
tree.right = self.addNode(tree.right, node, duplicates)
else:
tree.right = node
elif tree.value == node.value:
duplicates.append(node.value)
return tree
def buildTree():
arr = [14, 15, 4, 9, 7, 18, 3, 5, 16, 20,4,17, 9, 14, 5]
tree = Tree()
duplicates = []
for v in arr:
node = Node(v)
tree = tree.addNode(tree, node, duplicates)
s = json.dumps(tree.__dict__, default=serialize)
print(s)
print(duplicates)
def serialize(obj):
return obj.__dict__
if __name__ == '__main__':
buildTree()