Foro de elhacker.net

Programación => Ejercicios => Mensaje iniciado por: TomaSs en 29 Mayo 2012, 18:55 pm



Título: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 18:55 pm
Alguien sabría decirme si habría alguna fórmula o algoritmo para poder sacar la fila en la que te encuentras en cada momento?
Me explico, suponiendo que conocemos el número total de filas, que conocemos el número de nodo en el que nos encontramos, y el número de columna a la que pertenece dicho nodo, ¿habría algún algoritmo o fórmula para poder sacar la fila en la que se encuentra dicho nodo? Teniendo en cuenta que el árbol podría tener infinitas ramas, no únicamente los dos casos que muestro
Yo creo que algo se podrá hacer, pero le he dao mil vueltas y nada...

(http://oi49.tinypic.com/11sdp50.jpg)(http://oi45.tinypic.com/2vcz620.jpg)


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 19:22 pm
Te refieres a hallar la fila donde se encuentra el circulo con el numero 2 por ejemplo? esque no he aprendido todo eso, pero me aburro mucho y podria probar alguna forma de sacarlo si me aclaras eso, antes de que empieze a pensar al pedo xD


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 19:35 pm
Tu segunda imagen tendria que estar mal no? solo la recortaste, pero entonces queda mal porque falta el 3.

Despues la distribucion de la rama no se como se hace, si es asi siempre eso o que, si me explicas eso te ayudo


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 19:39 pm
cierto! está mal, porque la recorte si... bien visto! ;)
Pues me refiero a hallar la fila de cualquier nodo, es decir, busco una fórmula o algoritmo genérico para hallar cualquiera


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 19:45 pm
cabe decir que no se si tendrá alguna solución, ya que es algo que me ha surgido para hacer un programilla que estoy haciendo, no es que sea el enunciado de ningún ejercicio hecho. Pero creo que si puede tener un algoritmo genérico


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 19:45 pm
Pero es que yo no se bien sobre eso, pero como estoy aburrido puedo pensar algun algoritmo si me explicas.

Por ejemplo.. no me contestaste mi primer pregunta, lo de si un nodo es el numero del circulito.
Y por ejemplo, la distribucion de esos nodos, si es asi lo que es, quien dice como va? eso tambien cambiara?

Tu pones el primer circulo en la posicion 0,0 y el otro en la posicion 1,1, pero el siguiente (el del numero 2) lo pones en 2,3 . Por eso no se si eso cambiara y la formula tendra que partir de esa distribucion o que? explicame y te ayudo :P


Título: Re: Formula o algoritmo???
Publicado por: 79137913 en 29 Mayo 2012, 19:49 pm
HOLA!!!

Al fin un algoritmo complicado! me pongo a verlo!

GRACIAS POR LEER!!!


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 19:51 pm
Espera! no empezes, cuando me explique mis dudas, empeza a ver quien lo termina primero jeje


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 19:54 pm
Mi idea es pasar el árbol (sea del tamaño que sea) a filas ordenadas, pero como puedes ver, el arbol está ordenado en otro orden (el cual puedes ver siguiendo la numeración de los nodos).
De manera que yo obtendría, para el arbol grande, las siguientes filas:

-->0
-->1
-->4
-->2
-->5
-->6
-->7
-->3
-->8
-->9
-->11
-->10
-->12
-->13
-->14

Para lo cual debo sacar un algoritmo que me devuelva la fila, según el nodo. Entiendes?


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 20:00 pm
Contestame todas mis preguntas, no otra cosa que yo no he hecho esto nunca


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 20:03 pm
Pues la distribución siempre va a ser la misma, no se que más quieres que te explique jeje
Es decir, siempre va a seguir este esquema: http://oi47.tinypic.com/2dwcnes.jpg
teniendo en cuenta que siempre los nodos de la columna 0 van a ser potencias de 2, es decir, 2, 4, 8, 16, etc, pero el recorrido del arbol siempre se hará como en esta última foto


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 29 Mayo 2012, 20:08 pm
Bueno veo a ver si puedo, sino alguien lo hara


Título: Re: Formula o algoritmo???
Publicado por: 79137913 en 29 Mayo 2012, 21:07 pm
HOLA!!!

Mañana posteo.

GRACIAS POR LEER!!!


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 29 Mayo 2012, 22:55 pm
Bueno pues aquí va algo que he pensado, eso si, muy enrevesado... xddd
Es a nivel de programación, ya que algo a nivel matemático no he sido capaz de sacar.

• Tenemos el número total de filas: numFilas

• Dividimos dicho número de filas entre 2 para sacar el número de nodos de la columna 0:
   nodosCol0 = numFilas/2

• Calculamos el logaritmo en base 2 de nodosCol0 para sacar el número de columnas:
   numCol = log(nodosCol0)/log(2)

• Creamos una matríz [numCol X nodosCol0] que albergue por cada columna, los números de nodo que le pertenecen:
   Recorremos el arbol de la manera que hay que recorrerlo, desde el nodo 0--> http://oi47.tinypic.com/2dwcnes.jpg
   Puesto que para cada nodo conocemos su columna almacenamos cada uno en su registro de la matríz correspondiente, quedando la matríz de esta manera una vez recorrido todo el arbol:
   
   Col0-->0, 4, 5, 7, 8, 11, 12, 14
   Col1-->1, 6, 9, 13
   Col2-->2, 10
   Col3-->3


• Recorremos la matríz para sacar las filas de los nodos que contiene (suponiendo que la matríz comienza en 0):
   Obtenemos un multiplicador (multi) que, multiplicado por la posición de los nodos en la matríz, nos devolverá la fila que ocupa dicho nodo. De esta manera iremos almacenando las filas de cada nodo en un array, el cual contendrá todos los nodos ordenados por filas y no según el orden indicado inicialmente.

   for(p=0; p<=numCol; p++){

      multi = 2^(p+1);

      for(j=0; j<nodosCol0; j++){

         fila = j * multi + sumatorio(p);
         array[fila] = matriz[p][j];

      }
   }

• El array que obtendremos para el caso del árbol grande que he puesto en la foto sería el siguiente, es decir el orden "por filas" de los nodos:
   [0, 1, 4, 2, 5, 6, 7, 3, 8, 9, 11, 10, 12, 13, 14]


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 30 Mayo 2012, 13:37 pm
¿Como lo veis? a ver si alguien podría aportar algo más matemático, en caso de que fuera posible ;)


Título: Re: Formula o algoritmo???
Publicado por: 79137913 en 30 Mayo 2012, 13:53 pm
HOLA!!!

Hola, por metodos matematicos no pude resolver el problema (lamentable)...

Pero hice un codigo para que diseñe el arbol por si a alguien le sirve.

Código
  1. VERSION 5.00
  2. Begin VB.Form Form1
  3.   Caption         =   "Form1"
  4.   ClientHeight    =   3195
  5.   ClientLeft      =   60
  6.   ClientTop       =   345
  7.   ClientWidth     =   4680
  8.   LinkTopic       =   "Form1"
  9.   ScaleHeight     =   3195
  10.   ScaleWidth      =   4680
  11.   StartUpPosition =   3  'Windows Default
  12.   Begin VB.TextBox Text1
  13.      Height          =   3090
  14.      Left            =   150
  15.      MultiLine       =   -1  'True
  16.      TabIndex        =   0
  17.      Top             =   75
  18.      Width           =   2715
  19.   End
  20. End
  21. Attribute VB_Name = "Form1"
  22. Attribute VB_GlobalNameSpace = False
  23. Attribute VB_Creatable = False
  24. Attribute VB_PredeclaredId = True
  25. Attribute VB_Exposed = False
  26. Private Sub Form_Load()
  27. On Error GoTo ERR
  28. Show
  29. Dim n As Long
  30. Dim m As Long
  31. Dim suma As Long
  32. Dim grado As Long
  33. Dim Matriz() As Long
  34. Dim FLAG As Boolean
  35. Dim CERO As Long
  36.    n = InputBox("numero de filas//nodos (empezando de 0)")
  37.    m = InputBox("que numero de nodo busca?")
  38.    For X = 1 To n
  39.        suma = suma + 2 ^ X
  40.        If suma = n Then grado = X
  41.    Next
  42.    ReDim Matriz(n, grado)
  43.    For Y = 0 To grado
  44.        CERO = -1
  45.        For X = 0 To n
  46.            FLAG = False
  47.            For Z = 0 To Y - 1
  48.                If Matriz(X, Z) = 1 Then FLAG = True
  49.            Next
  50.            If FLAG = False Then CERO = X: Exit For
  51.        Next
  52.        For X = CERO To n Step 2 ^ (1 + Y)
  53.            Matriz(X, Y) = 1
  54.        Next
  55.    Next
  56. ERR:
  57.    For X = 0 To n
  58.        For Y = 0 To grado
  59.            ASD = ASD & Matriz(X, Y)
  60.        Next
  61.        Text1.Text = Text1.Text & vbNewLine & ASD
  62.        ASD = ""
  63.    Next  
  64. End Sub

GRACIAS POR LEER!!!


Título: Re: Formula o algoritmo???
Publicado por: TomaSs en 30 Mayo 2012, 17:20 pm
pero por lo que puedo ver, ahí no usas para nada el número de nodo que busca, el m, es porque al final solo hiciste que diseñara el arbol en vez de buscar su fila, no?

de todos modos, no es mal trabajo, aunque me cuesta un poco verlo con tanto bucle anidado haha


Título: Re: Formula o algoritmo???
Publicado por: 79137913 en 30 Mayo 2012, 17:52 pm
HOLA!!!

Mi idea era diseñar el arbol y luego recorrer la matriz de alguna manera y numerar los nodos, luego simplemente buscar el nodo nro sin requerir la columna.

Aunque con la manera que hago los nodos te puedo decir las filas de los nodos correspondientes a una columna.

GRACIAS POR LEER!!!


Título: Re: Formula o algoritmo???
Publicado por: $Edu$ en 31 Mayo 2012, 17:54 pm
Capas que hay alguna formula para hallarlos, seguramente si, pero si sos vos el que haces esa matriz, es facil recorrerla para saber cual es la fila, asi como dijo 79137913.

Es decir, si tenes una matriz [n][m], lo que haces es recorrer cada elemento hasta encontrar el nodo y ahi mostrar el valor de m y sera la fila. No vale la pena pensar una formula si lo podes hacer asi de facil.


Título: Re: Formula o algoritmo???
Publicado por: AgnesBlack en 23 Julio 2012, 15:28 pm
tarde respondo el mensaje y si hay un metodo es usando el metodo el Binary tree sort  o el de busqueda con puntero te dejo un ejemplo de uno que hice principio de año
este es con busqueda de puntero que es lo mas eficiente y rapido para buscar dicho nodo que buscas

Código:
unit uabb2;



{arbol binario de busqueda con punteros}



interface

type



  tipoClave=integer;

  tipoElemento=record

      clave:tipoClave;

  end;



  tipoPuntero=^tipoNodoArbol;

  tipoNodoArbol=record

      elemento:tipoElemento;

      izquierdo:tipoPuntero;

      derecho:tipoPuntero;

  end;



  tipoArbol=tipoPuntero;





var

  raizArbol:tipoArbol;



  procedure buscar(nodoArbol:tipoArbol; valorClave:tipoClave; var infoElemento:tipoElemento; var estaEnArbol:boolean);

  procedure insertar(var nodoArbol:tipoArbol; infoElemento:tipoElemento);

  procedure suprimir(var nodoArbol:tipoArbol; valorClave:TipoClave);

  procedure inOrden(nodoArbol:tipoArbol);

  procedure preOrden(nodoArbol:tipoArbol);

  procedure crearArbol(var nodoArbol:tipoArbol);

  function arbolVacio(nodoArbol:tipoArbol):boolean;



implementation



  procedure crearArbol(var nodoArbol:tipoArbol);

  begin

      raizArbol:=nil;

  end;





  procedure imprime(nodoArbol:tipoElemento);

  begin

       writeln('elemento ', nodoArbol.clave);

  end;





  function arbolVacio(nodoArbol:tipoArbol):boolean;

  begin

  if nodoArbol=nil then arbolVacio:=true

  else

      arbolVacio:=false;

  end;





  procedure preOrden(nodoArbol:tipoArbol);

  begin

      if not ArbolVacio(nodoArbol) then begin

         imprime(nodoArbol^.elemento);

         preOrden(nodoArbol^.izquierdo);

         preOrden(nodoArbol^.derecho);

      end

  end;

 



  procedure inOrden(nodoArbol:tipoArbol);

  begin

      if not ArbolVacio(nodoArbol) then begin

         inOrden(nodoArbol^.izquierdo);

         imprime(nodoArbol^.elemento);

         inOrden(nodoArbol^.derecho);

      end

  end;







  procedure buscar(nodoArbol:tipoArbol; valorClave:tipoClave; var infoElemento:tipoElemento; var estaEnArbol:boolean);

  var

     temp:tipoArbol;

  begin

       temp:=raizArbol;

       estaEnArbol:=false;



       while ((not ArbolVacio(temp)) and (not estaEnArbol)) do

           if temp^.elemento.clave=valorClave then

              estaEnArbol:=true

           else

               if temp^.elemento.clave>valorClave then

                   temp:=temp^.izquierdo

               else

                   temp:=temp^.derecho;



       if estaEnArbol then infoElemento:=temp^.elemento

  end;

 



  procedure insertar(var nodoArbol:tipoArbol; infoElemento:tipoElemento);

  var

     nuevoNodo:tipoArbol;

     temp,anterior:tipoArbol;

     claveNueva:tipoClave;

  begin

       new(nuevoNodo);

       nuevoNodo^.izquierdo:=nil;

       nuevoNodo^.derecho:=nil;

       nuevoNodo^.elemento:=infoElemento;



       claveNueva:=infoElemento.clave;



       temp:=nodoArbol;

       anterior:=nil;



       while not ArbolVacio(temp) do begin

           anterior:=temp;

           if temp^.elemento.clave>claveNueva then

              temp:=temp^.izquierdo

           else

              temp:=temp^.derecho

       end;



       if ArbolVacio(anterior) then {vacio}

           nodoArbol:=nuevoNodo

       else

           if anterior^.elemento.clave>claveNueva then

              anterior^.izquierdo:=nuevoNodo  {nuevo nodo a izq del padre}

           else

              anterior^.derecho:=nuevoNodo

  end;





  procedure suprimirNodo(var nodoArbol:tipoArbol; temp,anterior:tipoArbol);

  var

     auxiliar:tipoArbol;

  begin

      if (temp^.derecho=nil) and (temp^.izquierdo=nil) then

         if anterior=nil then

            nodoArbol:=nil {xq el arbol solo tenia un nodo!}

         else

            if anterior^.derecho=temp then  {eliminando una hoja}

                anterior^.derecho:=nil

            else

                anterior^.izquierdo:=nil



      else

          if (temp^.derecho<>nil) and (temp^.izquierdo<>nil) then begin

               anterior:=temp;

               auxiliar:=temp^.izquierdo;



               while auxiliar^.derecho<>nil do begin

                   anterior:=auxiliar;

                   auxiliar:=auxiliar^.derecho;

               end;



               temp^.elemento:=auxiliar^.elemento;

               if anterior=temp then

                   anterior^.izquierdo:=auxiliar^.izquierdo

               else

                   anterior^.derecho:=auxiliar^.izquierdo;



               temp:=auxiliar



          end

          else begin

               {el nodo tiene un hijo. debe subir}

               if temp^.derecho<>nil then {hijo derecho}

                  if anterior=nil then

                    anterior^.derecho:=temp^.derecho

                  else

                      if anterior^.derecho=temp then

                         anterior^.derecho:=temp^.derecho

                      else

                         anterior^.izquierdo:=temp^.derecho



               else {hijo izquierdo}

                    if anterior=nil then

                       anterior^.izquierdo:=temp^.izquierdo

                    else

                       if anterior^.derecho=temp then

                           anterior^.derecho:=temp^.izquierdo

                       else

                           anterior^.izquierdo:=temp^.izquierdo;

          end;





       dispose(temp);

  end;



  procedure suprimir(var nodoArbol:tipoArbol; valorClave:TipoClave);

  var

    temp, anterior:tipoArbol;

  begin

       temp:=nodoArbol;

       anterior:=nil;



       while temp^.elemento.clave<>valorClave do begin

           anterior:=temp;

           if temp^.elemento.clave>valorClave then

              temp:=temp^.izquierdo

           else

              temp:=temp^.derecho

       end;



       suprimirNodo(raizArbol,temp, anterior)

  end;







end.

ah traves de esto podes modificarlo para buscar el nodo que quieras y eliminarlo