如何在树 B 中进行函数搜索,return 节点的索引,必须在其中找到键?
How do I make my function search in a tree B, return the index of a node, in which the key must be found?
我正在尝试自己实现一个树B,insert_order可以工作,功能除法,但是搜索功能,我不知道如何实现它给我左边节点键的子节点。
这个是节点找的方法,如果没找到就returns -1,但是我要return连续键的位置(如果是找不到它,它是叶子)。
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
该方法在数组中有序插入,移动一个位置使数组重新排序
public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
这是一个向树中插入key的方法,如果是叶子就调用insert_order,但是如果不是叶子就递归调用直到到达叶子,如果到达叶子它应该调用 insert_order.
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
我留下了所有代码,以防有人想更详细地查看它
package ARBOL_B;
public class 树B {
Nodo root;
public treeB(int grado){
root = new Nodo(grado);
}
public boolean exist(Nodo nodo, int valor){
int i =0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i+1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return true;
}
if(nodo.isLeaf()){
return false;
}else{
return exist(nodo.sons[i], valor);
}
}
/*
This is the method that the node finds, if it doesn't find it it returns -1, but I want it to return the position of the continuous key (if it can't find it and it's leaf).
* */
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
/*
该方法在数组中有序插入,
移动一个位置以重新排列数组
*/
public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
boolean first_time = true;
/*
this is a method that inserts a key into the tree,
if it is a leaf it calls insert_order, but if it is not a leaf it
calls recursively until reaching a leaf, if it reaches a leaf
it should call insert_order
* */
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
public Nodo divide(Nodo nodo){
Nodo new_node = new Nodo(nodo.degree);
new_node.keys = new int[nodo.degree];
new_node.sons = new Nodo[nodo.degree];
for(int i = (int)(Math.ceil(nodo.degree/2)), j = 0; i < nodo.degree; i++, j++){
new_node.keys[j] = nodo.keys[i];
nodo.keys[i] = 0;
if(!nodo.isLeaf()){
new_node.sons[j+1] = nodo.sons[i+1];
nodo.sons[i+1] = null;
}
}
if(nodo.isLeaf()){
nodo.numKeys = (int)(Math.ceil(nodo.degree/2));
new_node.numKeys = nodo.degree - nodo.numKeys;
}
return new_node;
}
public boolean estaVacia(int[] claves){
for(int i = 0; i < root.numKeys; i++){
if(claves[i] != 0){
return false;
}
}
return true;
}
public static String print(int[] list){
String str = "";
for(int i = 0;i < list.length; i++){
str += list[i]+ "; ";
}
return str;
}
public static void printSons(Nodo[] sons){
String str = "";
for(int i = 0; i < sons.length; i ++ ){
if(sons[i] != null)
str += " [ "+print(sons[i].keys)+ " ] , ";
}
System.out.println(str);
}
public static void main(String[] args) {
treeB bb = new treeB(3);
bb.root.keys = new int[3];
bb.root.sons = new Nodo[3];
Nodo nuevo = bb.insertion(bb.root, 3);
System.out.println(print(bb.root.keys));
nuevo = bb.insertion(bb.root, 1);
System.out.println(print(bb.root.keys));
System.out.println(bb.root.numKeys);
System.out.println(bb.root.numSons);
nuevo = bb.insertion(bb.root, 2);
System.out.print(bb.root.numSons+"<");
System.out.print(bb.root.sons[1].numKeys);
nuevo = bb.insertion(bb.root, 4);
System.out.println(print(bb.root.keys));
printSons(bb.root.sons);
}
}
这是 class 节点。
public class 诺多{
int degree;
int []keys = new int[degree];// es hasta N-1, pero se necesita un espacio mas
int numKeys = 0;
Nodo[] sons = new Nodo[degree];
int numSons = 0;
public Nodo(int grado){
this.degree = grado;
}
public Nodo(){ }
public boolean isLeaf(){
for(int i = 0 ; i < this.numSons; i++){
if(this.sons[i] != null){
return false;
}
}
return true;
}
}
我希望你能帮助我,我不知道如何让我找到 return 正确的密钥,如果有人有更好的方法,我将感谢你的支持,在此先感谢。 :)
我设法实现了搜索方法,我的解决方案是 return 当前节点,而不是位置,我做了一个 class 将节点和键数组中的位置打包, 就是找不到。
public wrapp search_2(Node node, int valor){
wrapp em;
int i = 0;
while(i < node.numKeys && node.keys[i] < valor){
i = i + 1;
}
if(i < node.numKeys && node.keys[i] == valor){
em = new wrapp(null,-1);
return em;
}
if(node.isLeaf()){
em = new wrapp(node,i);
return em;
}else{
return search_2(node.sons[i], valor);
}
}
问题是找到当前节点,认为它会 return child 的位置,而实际上 return 相同的节点
我正在尝试自己实现一个树B,insert_order可以工作,功能除法,但是搜索功能,我不知道如何实现它给我左边节点键的子节点。
这个是节点找的方法,如果没找到就returns -1,但是我要return连续键的位置(如果是找不到它,它是叶子)。
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
该方法在数组中有序插入,移动一个位置使数组重新排序
public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
这是一个向树中插入key的方法,如果是叶子就调用insert_order,但是如果不是叶子就递归调用直到到达叶子,如果到达叶子它应该调用 insert_order.
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
我留下了所有代码,以防有人想更详细地查看它
package ARBOL_B;
public class 树B {
Nodo root;
public treeB(int grado){
root = new Nodo(grado);
}
public boolean exist(Nodo nodo, int valor){
int i =0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i+1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return true;
}
if(nodo.isLeaf()){
return false;
}else{
return exist(nodo.sons[i], valor);
}
}
/*
This is the method that the node finds, if it doesn't find it it returns -1, but I want it to return the position of the continuous key (if it can't find it and it's leaf).
* */
public int search(Nodo nodo, int valor){
int i = 0;
while(i < nodo.numKeys && nodo.keys[i] < valor){
i = i + 1;
}
if(i < nodo.numKeys && nodo.keys[i] == valor){
return i;
}
if(nodo.isLeaf()){
return -1;
}else{
return search(nodo.sons[i], valor);
}
}
/* 该方法在数组中有序插入, 移动一个位置以重新排列数组 */ public void insert_order(Nodo nodo, int value, Nodo right_son){
if(estaVacia(nodo.keys)){
nodo.keys[nodo.numKeys] = value;
nodo.sons[1] = right_son;
nodo.numSons++;
}else{
int pivote = 0;
while(pivote < nodo.numKeys&&nodo.keys[pivote] < value){
pivote = pivote + 1;
}
for(int i = nodo.numKeys-1; i >= pivote; --i ){
nodo.keys[i+1] = nodo.keys[i];
}
for(int i = nodo.numSons-1; i >= pivote; --i){
nodo.sons[i+1] = nodo.sons[i];
}
nodo.keys[pivote] = value;
nodo.sons[pivote+1] = right_son;
}
nodo.numKeys++;
if(!nodo.isLeaf()){
nodo.numSons++;
}
}
boolean first_time = true;
/*
this is a method that inserts a key into the tree,
if it is a leaf it calls insert_order, but if it is not a leaf it
calls recursively until reaching a leaf, if it reaches a leaf
it should call insert_order
* */
public Nodo insertion(Nodo nodo, int value){
if(nodo.isLeaf()){
insert_order(nodo, value, null);
}else{
int i = search(nodo,value);
Nodo nuevo = null;
if(i!=-1){//<-- is leaf and return -1 :(
throw new RuntimeException("exist this key");
}else{
//error: Array index of bounds Exception : -1
nuevo = insertion(nodo.sons[i], value);
}
if(nuevo != null){
int pivote = nuevo.keys[0];
insert_order(nodo, pivote, nuevo);
for(int k = 0; k <= nodo.numKeys-1; k++ ){
nodo.keys[k] = nodo.keys[k+1];
}
}
}
if (nodo.numKeys > nodo.degree -1){
Nodo new1 = divide(nodo);
/*
* the root was divided, the new node will be the right child
* and all that remains is to upload the root to the father,
* but since this is the first time, the root will divide and
* redefine the root.
*
* */
if(first_time && new1 != null ){
int pivote1 = new1.keys[0];
Nodo izquierda = nodo;
Nodo new_root = new Nodo(root.degree);
new_root.keys = new int [root.degree];
new_root.sons = new Nodo[root.degree];
insert_order(new_root,pivote1, new1);
root = new_root;
int pivotem = 0;
while(root.keys[pivotem] < pivote1){
pivotem = pivotem + 1;
}
root.sons[pivotem] = izquierda;
for(int k = 0; k <= new1.numKeys-1; k++ ){
new1.keys[k] = new1.keys[k+1];
}
new1.numKeys--;
first_time = false;
}
return new1;
}else{
return null;
}
}
public Nodo divide(Nodo nodo){
Nodo new_node = new Nodo(nodo.degree);
new_node.keys = new int[nodo.degree];
new_node.sons = new Nodo[nodo.degree];
for(int i = (int)(Math.ceil(nodo.degree/2)), j = 0; i < nodo.degree; i++, j++){
new_node.keys[j] = nodo.keys[i];
nodo.keys[i] = 0;
if(!nodo.isLeaf()){
new_node.sons[j+1] = nodo.sons[i+1];
nodo.sons[i+1] = null;
}
}
if(nodo.isLeaf()){
nodo.numKeys = (int)(Math.ceil(nodo.degree/2));
new_node.numKeys = nodo.degree - nodo.numKeys;
}
return new_node;
}
public boolean estaVacia(int[] claves){
for(int i = 0; i < root.numKeys; i++){
if(claves[i] != 0){
return false;
}
}
return true;
}
public static String print(int[] list){
String str = "";
for(int i = 0;i < list.length; i++){
str += list[i]+ "; ";
}
return str;
}
public static void printSons(Nodo[] sons){
String str = "";
for(int i = 0; i < sons.length; i ++ ){
if(sons[i] != null)
str += " [ "+print(sons[i].keys)+ " ] , ";
}
System.out.println(str);
}
public static void main(String[] args) {
treeB bb = new treeB(3);
bb.root.keys = new int[3];
bb.root.sons = new Nodo[3];
Nodo nuevo = bb.insertion(bb.root, 3);
System.out.println(print(bb.root.keys));
nuevo = bb.insertion(bb.root, 1);
System.out.println(print(bb.root.keys));
System.out.println(bb.root.numKeys);
System.out.println(bb.root.numSons);
nuevo = bb.insertion(bb.root, 2);
System.out.print(bb.root.numSons+"<");
System.out.print(bb.root.sons[1].numKeys);
nuevo = bb.insertion(bb.root, 4);
System.out.println(print(bb.root.keys));
printSons(bb.root.sons);
}
} 这是 class 节点。
public class 诺多{
int degree;
int []keys = new int[degree];// es hasta N-1, pero se necesita un espacio mas
int numKeys = 0;
Nodo[] sons = new Nodo[degree];
int numSons = 0;
public Nodo(int grado){
this.degree = grado;
}
public Nodo(){ }
public boolean isLeaf(){
for(int i = 0 ; i < this.numSons; i++){
if(this.sons[i] != null){
return false;
}
}
return true;
}
} 我希望你能帮助我,我不知道如何让我找到 return 正确的密钥,如果有人有更好的方法,我将感谢你的支持,在此先感谢。 :)
我设法实现了搜索方法,我的解决方案是 return 当前节点,而不是位置,我做了一个 class 将节点和键数组中的位置打包, 就是找不到。
public wrapp search_2(Node node, int valor){
wrapp em;
int i = 0;
while(i < node.numKeys && node.keys[i] < valor){
i = i + 1;
}
if(i < node.numKeys && node.keys[i] == valor){
em = new wrapp(null,-1);
return em;
}
if(node.isLeaf()){
em = new wrapp(node,i);
return em;
}else{
return search_2(node.sons[i], valor);
}
}
问题是找到当前节点,认为它会 return child 的位置,而实际上 return 相同的节点