none
Problema con árbol binario de búsqueda en Visual C# 2008 RRS feed

  • Pregunta

  • Hola a todos. Qusieran que me ayudaran con este pequeño problema que tengo.

    Soy algo nueva en la programación de estructuras de datos, y estoy diseñando un árbol binario de búsqueda en Visual C# 2008. El problema que tengo es que parece que no se insertan los nodos, por lo que al realizar el recorrido siempre el valor que sale es cero. El formulario que se encarga de mostrar los resultados se encarga de llamar las funciones que se encuentran contenidas en una clase a la que llamé Nodo_Busqueda.

    Este es el primer código que puse:

    public void recibir()

            {

                Nodo_Busqueda raiz = null;

                int dato;

                Boolean control = true;

     

                while (control)

                {

                    try

                    {

                        InputBox frminput = new InputBox();

                        frminput.ShowDialog();

                        dato = Convert.ToInt32(frminput.txtentrada.Text);

                        if (raiz == null)

                        {

                            Nodo_Busqueda nodonuevo = new Nodo_Busqueda();

                            nodonuevo.informacion = dato;

                            raiz = nodonuevo;

                        }

                        else

                        {

                            insertar(raiz, dato);

                        }

     

                        DialogResult respt;

                        respt = MessageBox.Show("¿Desea insertar otro nodo?", "Mensaje", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);

                        if (respt == System.Windows.Forms.DialogResult.Yes)

                        {

                            recibir();

                        }

                        control = false;

                    }

                    catch (FormatException e)

                    {

                        MessageBox.Show("Error: " + e.Message + "\nPor favor, ingrese valores de tipo entero positivo.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    }

                }  

            }

           

            public void insertar(Nodo_Busqueda raiz,int dato)

            {

                if (dato < raiz.informacion)

                {

                    if (raiz.izq == null)

                    {

                        Nodo_Busqueda nodonuevo = new Nodo_Busqueda();

                        nodonuevo.informacion = dato;

                        raiz.izq = nodonuevo;

                    }

                    else

                    {

     

                        insertar(raiz.izq, dato);

                    }

                }

                else

                {

                    if (dato > raiz.informacion)

                    {

                        if (raiz.der == null)

                        {

                            Nodo_Busqueda nodonuevo = new Nodo_Busqueda();

                            nodonuevo.informacion = dato;

                            raiz.der = nodonuevo;

                        }

                        else

                        {

                            insertar(raiz.der, dato);

                        }

                    }

                }   

            }



    Este otro código que hice si inserta los nodos, pero el problema es que parece que el último valor que se introduce reemplaza al anterior(si se introducen 3 nodos, sólo aparecen 2, etc.)

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Text;

    using System.Windows.Forms;

     

    namespace Proyecto

    {

        class Nodo_Busqueda

        {

            public Nodo_Busqueda izq;

            public Nodo_Busqueda der;

            public int informacion;

           

          

            public Nodo_Busqueda()

            {

                izq = null;

                der = null;

                informacion = 0;

               

            }

     

            public void recibir(Nodo_Busqueda raiz)

            {

               

                int dato;

                Boolean control = true;

               

                while (control)

                {

                    try

                    {

                        InputBox frminput2 = new InputBox();

                        frminput2.ShowDialog();

                        dato = Convert.ToInt32(frminput2.txtentrada.Text);

                      

                        raiz.informacion = dato;

     

                        DialogResult respt;

                        respt = MessageBox.Show("¿Desea insertar otro nodo?", "Mensaje", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);

                        if (respt == System.Windows.Forms.DialogResult.Yes)

                        {

                           

                            insertar(raiz,dato);

                        }

                        

                        control = false;

                    }

                    catch(FormatException e)

                    {

                        MessageBox.Show("Error: " + e.Message + "\nPor favor, ingrese valores de tipo entero positivo.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    }

       

                }

              

            }

           

            public void insertar(Nodo_Busqueda raiz,int dato)

            {

               

                InputBox frminput = new InputBox();

                frminput.ShowDialog();

                dato = Convert.ToInt32(frminput.txtentrada.Text);

     

                if (dato < raiz.informacion)

                {

                    if (raiz.izq == null)

                    {

                        Nodo_Busqueda nodonuevo = new Nodo_Busqueda();

                        nodonuevo.informacion = dato;

                        raiz.izq = nodonuevo;

                    }

                    else

                    {

                      

                        insertar(raiz.izq, dato);

                    }

                }

                else

                {

                    if (dato > raiz.informacion)

                    {

                        if (raiz.der == null)

                        {

                            Nodo_Busqueda nodonuevo = new Nodo_Busqueda();

                            nodonuevo.informacion = dato;

                            raiz.der = nodonuevo;

                        }

                        else

                        {

                           

                            insertar(raiz.der, dato);

                        }

                    }

                }

     

                DialogResult respt;

                respt = MessageBox.Show("¿Desea insertar otro nodo?", "Mensaje", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);

                if (respt == System.Windows.Forms.DialogResult.Yes)

                {

                    insertar(raiz, dato);

                }   

            }

     

     

     



    Espero que me puedan ayudar con esto. Y muchas gracias de antemano por su ayuda!



    viernes, 13 de noviembre de 2009 2:07

Respuestas

  • Solo he examinado la primera de las dos funciones que has puesto. Tu función "recibir" se va llamando recursivamente a sí misma para recoger nuevos valores e irlos almacenando. Estos valores se almacenan en un árbol que cuelga de "raiz". El problema es que raiz es una variable local del método recursivo, por lo que a cada recursión se crea una nueva copia de raiz y por tanto un nuevo árbol que no tienen ningún dato más que ese nodo raiz. Al salir de la recursión, la variable se pierde y el árbol queda vacío.

    Puedes solucionarlo sacando esa variable de la función y declarándola a nivel de clase.

    Otro problema que observo en el método insertar es que solo compruebas si el dato es menor o mayor que raiz.información. Pero si es exactamente igual, se desprecia silenciosamente y no se inserta.
    • Marcado como respuesta Zoe091245 sábado, 14 de noviembre de 2009 7:46
    viernes, 13 de noviembre de 2009 12:32
    Moderador

Todas las respuestas

  • Solo he examinado la primera de las dos funciones que has puesto. Tu función "recibir" se va llamando recursivamente a sí misma para recoger nuevos valores e irlos almacenando. Estos valores se almacenan en un árbol que cuelga de "raiz". El problema es que raiz es una variable local del método recursivo, por lo que a cada recursión se crea una nueva copia de raiz y por tanto un nuevo árbol que no tienen ningún dato más que ese nodo raiz. Al salir de la recursión, la variable se pierde y el árbol queda vacío.

    Puedes solucionarlo sacando esa variable de la función y declarándola a nivel de clase.

    Otro problema que observo en el método insertar es que solo compruebas si el dato es menor o mayor que raiz.información. Pero si es exactamente igual, se desprecia silenciosamente y no se inserta.
    • Marcado como respuesta Zoe091245 sábado, 14 de noviembre de 2009 7:46
    viernes, 13 de noviembre de 2009 12:32
    Moderador
  • hola

    por ahi lo que tendria para aportar es que realizas el procesamiento y la definicion de nodos en la misma clase, por ahi esto puede confundir un poco.

    Me refiero a que el Nodo_Busqueda es en si mismo al definicion del nodo al tener las propeidades, y los metodos.

    No seria conveniente separarlos, para que el codigo divida responsabildiades, o sea que el procesamiento y armado del nodo este por fuera y no se creen instancias a si mismo

    Por un lado poner


    public class Nodo
    {
            public Nodo_Busqueda izq {get; set;};

            public Nodo_Busqueda der {get; set;};

            public int informacion {get; set;};


    }


    y por el otro al clase


    public class ProcessNodos
    {
         public void recibir(Nodo raiz)
         {
           ...
         }

         public void insertar(Nodo raiz,int dato)
         {
          ...
         }

    }


    Ademas seria bueno si usas propiedades para definir los atributos del nodo, en lugar de variable declaradas como publicas


    saludos
    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    viernes, 13 de noviembre de 2009 13:23
  • Hola Alberto Población:

    Te informo que ya solucioné el problema con el código. Tuve que modificar  el cçodigo que hacía los recorridos en el árbol.

    Y sobre lo que dices de que si el dato es igual a raiz.información el dato se desprecia y no se inserta, es cierto. Es así para que no haya nodos con valores repetidos.


    Gracias por tomarte tu tiempo para responder, al igual que a Leandro Tuttini.

    Saludos y gracias nuevamente!!!
    sábado, 14 de noviembre de 2009 7:51
  • Hola,

    Aqui hay un ejemplo de arbol binario de busqueda en C#

    http://xgeeker.blogspot.com/2012/11/ejemplo-de-arbol-binario-de-busqueda-en.html

    Saludos



    Jose Mendez.
    Blog
    Ejemplos de codigos/Code Samples
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Si un Post responde a tu pregunta, por favor "Marcala como Respondida" y "Vota como útil".

    miércoles, 5 de diciembre de 2012 18:56