- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须从树中消除一个节点。我首先尝试消除节点根,这样我就不必搜索节点并且它可以工作。但后来我尝试通过搜索来做到这一点,当函数调用自身时,程序在通过第一个 if 语句后卡住......
问题出在函数中,void Eliminar(struct arbol *tree, int valor);
:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct arbol
{
int numero;
struct arbol *izq;
struct arbol *der;
};
struct arbol *raiz = NULL;
struct arbol *eliminador = NULL;
int encontrado = 0;
int right = 0, left = 0;
int crear_arbol(int dato);
struct arbol * crear_nodo(int valor);
void ImprimeDNI (struct arbol *tree);
void ImprimeIND (struct arbol *tree);
void ImprimeNDI (struct arbol *tree);
void Buscar (struct arbol *tree, int valor);
void Eliminar (struct arbol *tree,int valor);
int Eliminaroot ();
int Eliminarright(struct arbol *localizador);
int Eliminarleft(struct arbol *localizador);
int main ()
{
int n, i;
char opcion;
int numero;
puts("Ingrese la cantidad de numeros a ingresar");
scanf("%d", &n);
int numeros[n];
puts("Ingrese los numeros separados por espacio o enter");
for(i = 0; i < n; i++)
{
scanf("%d",&numeros[i]);
}
for(i = 0; i < n; i++)
{
crear_arbol(numeros[i]);
}
puts("");
system("pause");
system("cls");
do
{
encontrado = 0;
puts("******** OPCIONES ********");
puts("|B o b| Para buscar un numero");
puts("|E o e| Eliminar un nodo");
puts("|I o i| Imprimir de las 3 formas principales");
fflush(stdin);
opcion = getch();
switch(opcion)
{
case 'B': case 'b': puts("Ingrese el numero a buscar"); scanf("%d",&numero); Buscar(raiz,numero);
if(encontrado == 0) {puts("El numero no esta en el arbol");} break;
case 'E': case 'e': puts("Ingrese el numero a eliminar"); scanf("%d", &numero);
if(raiz->numero == numero)
{
Eliminaroot();
}
else
{
Eliminar(raiz,numero);
if(right == 0 && left == 0)
{
puts("No se encontro el numero");
}
if(right == 1)
{
Eliminarright(eliminador);
}
if(left == 1)
{
Eliminarleft(eliminador);
}
}
break;
case 'I': case 'i': ImprimeDNI(raiz); puts(""); ImprimeIND(raiz); puts(""); ImprimeNDI(raiz); puts(""); break;
default: puts("Opcion Invalida"); break;
}
puts("");
system("pause");
system("cls");
}while (opcion != 'T' || opcion != 't');
return 0;
}
int crear_arbol(int dato)
{
struct arbol *recorrer = raiz;
struct arbol *nuevo;
if(raiz == NULL)
{
raiz = crear_nodo(dato);
return 1;
}
else
{
nuevo = crear_nodo(dato);
}
while (1) {
if(recorrer->numero <= nuevo->numero)
{
if(recorrer->der == NULL)//si las ramas de donde esta el puntero que recorre son NULL, significa
{ //que es la ultima comparacion
recorrer->der = nuevo;
break;
}
recorrer = recorrer->der;
}
else
{
if(recorrer->izq == NULL)//lo mismo que el if de arriba
{
recorrer->izq = nuevo;
break;
}
recorrer = recorrer->izq;
}
}//while
return 1;
}
struct arbol * crear_nodo(int valor)
{
struct arbol *aux;
aux = (struct arbol*)malloc(sizeof(struct arbol));
aux->numero = valor;
aux->izq = NULL;
aux->der = NULL;
return aux;
}
void ImprimeDNI (struct arbol *tree)
{
if(!tree)
return;
ImprimeDNI(tree->der);
printf("%d, ", tree->numero);
ImprimeDNI(tree->izq);
}
void ImprimeIND (struct arbol *tree)
{
if(!tree)
return;
ImprimeIND(tree->izq);
printf("%d, ", tree->numero);
ImprimeIND(tree->der);
}
void ImprimeNDI (struct arbol *tree)
{
if(!tree)
return;
printf("%d, ", tree->numero);
ImprimeNDI(tree->der);
ImprimeNDI(tree->izq);
}
void Buscar (struct arbol *tree, int valor)
{
if(tree->numero == valor)
{printf("El numero si se encuentra en el arbol"); encontrado = 1;}
if(!tree)
return;
Buscar(tree->der, valor);
Buscar(tree->izq,valor);
}
int Eliminaroot ()
{
int encontrado = 0;
struct arbol *aux = raiz;
struct arbol *buscador = raiz->der;
for(; buscador->der != NULL ; buscador = buscador->der)
{
if(buscador->izq != NULL)
{
encontrado = 1;
for(; buscador->izq->izq != NULL ; buscador = buscador->izq)
{
}
break;
}//if
}
if(encontrado == 0)
{
if(raiz->der == NULL)
{
raiz = aux->izq;
raiz->izq = aux->izq->izq;
raiz->der = aux->izq->der;
}
else
{
raiz = aux->der;
raiz->izq = aux->izq;
raiz->der = aux->der->der;
free(aux);
}
}
else
{
raiz = buscador->izq;
raiz->der = aux->der;
raiz->izq = aux->izq;
buscador->izq = NULL;
free(aux);
}
return 1;
}
void Eliminar (struct arbol *tree, int valor)
{
if(tree->izq->numero == valor)
{
eliminador = tree;
left = 1;
}
puts("AAAA");
if(tree->der->numero == valor)
{
eliminador = tree;
right = 1;
}
if(!tree)
return;
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
int Eliminarright(struct arbol *localizador)
{
return 1;
}
int Eliminarleft(struct arbol *localizador)
{
return 1;
}*
最佳答案
正如 Nick 建议的那样,您应该检查 tree
在 Eliminar
开头是否有效。但是,如果第一个 if
语句执行正常,则 tree
不能为 NULL
。不过, tree->der
可以 - 您也应该在取消引用之前检查它。当然,第一个 if 中的 tree->izq
也是如此 - 只是因为它在您第一次调用此函数时不为 NULL,所以不要假设它永远不会。
一些进一步的说明:您正在 Elimar
中搜索具有值 valor
的节点(因此这是一个坏名字 - 您并没有消除那里的节点,仅将其标记为以后删除)。
如果找到它,则没有必要继续搜索,因此您可以立即从两个 if
分支返回
。
此外,通过设置 left
或 right
标志,可以单独处理在左子树或右子树中找到 valor
的情况,并相应地调用Eliminarleft
或Eliminarright
。直接存储要删除的左子树或右子树会更简单,因此您可以删除两个标志和两个删除方法:
void Eliminar (struct arbol *tree, int valor)
{
if(!tree)
return;
if(tree->izq && tree->izq->numero == valor)
{
eliminador = tree->izq;
return;
}
puts("AAAA");
if(tree->der && tree->der->numero == valor)
{
eliminador = tree->der;
return;
}
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
...
Eliminar(raiz,numero);
if(!eliminador)
{
puts("No se encontro el numero");
}
else
{
Eliminar(eliminador);
}
这更干净,但我们可以走得更远。请注意,您正在检查 Eliminar 中的左子树和右子树,然后对其进行递归。只需检查 tree
本身就足够了,然后递归:
void Eliminar (struct arbol *tree, int valor)
{
if(!tree)
return;
if(tree->numero == valor)
{
eliminador = tree;
return;
}
puts("AAAA");
Eliminar(tree->der, valor);
Eliminar(tree->izq, valor);
}
关于c - 从树中删除节点函数在 C 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10040552/
我正在使用 JavaFX 8 创建一个应用程序。我使用拖/放动态更改网格 Pane 的内容。我希望每行或每行/列迭代 GridPane 内容。JavaFX 允许通过指定行和列在 GridPane 中添
我正在尝试将图像拖放到div上。图像没有被拖到div上并给出以下错误 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': pa
我正在 android studio 中创建内部构建 AR 导航。我正在寻找一种方法将 anchor 与其他 anchor 或 anchor 节点/节点“连接”起来。我不确定使用哪一个。基于我将强制用
我在 Hive 上运行一些作业:首先是 4 节点,然后是 2 节点。令我惊讶的是,我的 2 节点性能比我的 4 节点更好。 首先,我在一个 4 节点(4 个事件节点)上运行查询,然后关闭 2 个节点(
我有 Node* current ,我在其中存储指向列表“顶部”当前节点的指针。当我将一个新节点设置为当前节点时,出现错误: '=' : cannot convert from 'CircularDo
我是 dcos Mesos 的新手,在本地 Ubuntu 机器上安装了 dc os。 我可以查看 dcos 仪表板。 但我无法使用 dcos node ssh --master-proxy --lea
在 JavaFX 中,是否有类似 setLayout(); 的东西?或 setBounds(); ? 例如,我想将按钮定位到我想要的位置。 最佳答案 JavaFX 场景图上的所有内容都是 Node .
我正在开发一个 JavaFX 应用程序,其中我开发的类(从 javafx.scene.Parent 扩展)是根据用户在 ListView 控件中单击的条目动态创建的。 只是要清楚这个节点,它不是使用像
我正在尝试为节点-边缘关系创建一个类图,因为它可以在有向图中找到。我想传达的是,Nodes 引用了 Edges,Edges 也引用了 Nodes。每个 Edge 都恰好需要两个 Node(源和目标)。
在mapreduce作业期间,单个任务将在随机节点上运行,是否有任何方法限制应在其中运行任务的节点? 最佳答案 Hadoop不会选择节点来随机运行任务。考虑到数据局部性,否则将有很多网络开销。 任务与
有什么区别: a) nodetool 重建 b) nodetool 修复 [-pr] 换句话来说,各个命令到底是做什么的? 最佳答案 nodetool重建:类似于引导过程(当您向集群添加新节点时),但
我已将第一个 OneToMany 关系添加到我的 hibernate 3.6.10 项目中。这是一个类: /** * */ package com.heavyweightsoftware.leal
是否有可能找到正在监听触发当前函数的事件的元素? 在下面的代码中,event.target 返回 #xScrollPane 和 event.currentTarget 和 event 的最低子节点.f
我正在尝试覆盖我数据库中的一些数据。结构很简单,就是: recipes { user_1{ recipe_1{data} recipe_2{data} } user_2{
我使用 setInterval 来运行该函数,但它会多次执行函数 2... 如何在输入中插入一个值后执行函数 第一个输入与其余输入的距离不同 如何在插入 val(tab 选项)后将插入从 1 个输入移
我不知道代码有什么问题,但在 visual studio 中不断收到这些错误消息。 Error 18 error C1903: unable to recover from previous e
我正在尝试从其类中获取 SharePoint 搜索导航节点的对象。 var nodes = $("div.ms-qSuggest-listItem"); 我正在获取节点对象,现在想要获取“_promp
D:\nodeP>node main.js module.js:327 抛出错误; ^ 错误:在 Function.Module 的 Function.Module._resolveFilename
struct node{ int key, prior, cnt, val; node *l, *r; node(){} node(int nkey) : key(nkey),
我有以下代码使用迭代器将项目插入双链表。这就是我们被要求这样做的方式。代码有效,但问题是我有 24 字节的绝对内存泄漏。 NodeIterator insert(NodeIterator & itrP
我是一名优秀的程序员,十分优秀!