Académique Documents
Professionnel Documents
Culture Documents
INTRODUCCIN.
El presente trabajo pretende servir como referencia a los alumnos (y docentes) de las carreras de Ingeniera en Sistemas Computacionales e Ingeniera en Informtica que oferta la DGEST (retculas 2010). Se asume que el estudiante tiene cierta experiencia en el manejo del lenguaje VB.NET. En esta institucin, cuando he tenido oportunidad, he impartido las materias que son competencias previas a Estructura de Datos (Fundamentos de Programacin y Programacin Orientada a Objetos) usando el lenguaje de programacin Visual Basic .NET . De manera que el trnsito por la materia objeto de este libro es bastante amigable. Se ha usado una extraa mezcla de ingles espaol con el fin de no usar la traduccin literal de las palabras reservadas del lenguaje para tratar de evitar confusiones en los alumnos. Es claro que en la prctica real, las estructuras de datos juegan un papel preponderante, as que la importancia de esta materia en la formacin de futures desarrolladores de software no tiene lugar a dudas. Muchos de los casos aqu expuestos han sido tomados de la prctica profesional personal a lo largo de muchos de los sistemas que he tenido la fortuna de implementar. Otros casos son revisiones del material de varios de los autores clsicos de esta materia. El enfoque por competencias que se ha pretendido dar hace que el enfoque sea mucho ms prctico que terico, el estudiante deber escribir los programas aqu presentados con el fin de alcanzar las competencias especficas que establece el programa de la materia y as mismo, realizar los ejercicios propuestos. Es recomendable, cuando sea posible, que los estudiantes asistan a las exposiciones con una lap, al menos una por grupo de trabajo, dadas las limitaciones, que como en el caso nuestro, existen en los laboratorios de cmputo. En esos equipos debe estar instalado al menos la ltima version VBEE [edicin express] (que es gratuita) disponible en los sitios de Microsoft. La idea es que el estudiante escriba todos los programas que se muestran en este texto, tratando de evitar la nociva prctica de copiar pegar, razn por la cual no se proporciona el cdigo fuente de estos. Habr que teclear lnea por lnea. DEDICATORIAS: El trabajo diario de un programador trae consigo una serie de privaciones sobre todo en la familia, quiero dedicar este trabajo a mi esposa Susana, a mis hijos Ricardo y Sandra quienes soportaron privaciones sobre todo en el tiempo que deb dedicarles. A mi nieta Carolina quien vino a darme una nueva oportunidad de reponer ese tiempo y ha sido una nueva luz en mi vida. Quiz tarde he comprendido la importancia de administrar el tiempo en la tarea del desarrollo de sistemas evitando la obsesion de terminar alguna tarea a como d lugar y nunca quitar tiempo de dedicacin a la familia.
Ricardo Alfonso Almanza Mrquez
Tabla de contenido
Introduccin a las Estructuras de Datos ................................................................ 5 Definiciones ...................................................................................................... 5 Tipos de datos abstractos (TDA) .................................................................... 6 Arreglos ....................................................................................................... 21 Recursividad....................................................................................................... 67 Estructuras Lineales............................................................................................ 73 Listas .............................................................................................................. 73 Lista ligada simple ....................................................................................... 74 Lista ligada doble ......................................................................................... 82 Lista circular ................................................................................................ 94 Pilas .............................................................................................................. 103 Estructuras No Lineales .................................................................................... 127 rboles ...................................................................................................... 127 rboles Binarios ......................................................................................... 128 rboles balanceados .................................................................................. 139 Grafos........................................................................................................ 141 Mtodos de Ordenamiento ............................................................................... 151 Ordemamiento por seleccin ..................................................................... 153 Ordenamiento de la burbuja ...................................................................... 157 Ordenamiento rpido (Quick Sort ............................................................... 159 Ordenamiento por acumulacin (Heap Sort) ............................................... 162 Ordenamiento por mezcla (Merge Sort) ...................................................... 167 Ordenamiento externo ............................................................................... 169 Mtodos de Bsqueda ...................................................................................... 177 Bsqeda secuencial .................................................................................... 177 3
Bsqueda binaria ....................................................................................... 179 Bsqueda por funciones Hash .................................................................... 180 Anlisis de algoritmos ...................................................................................... 191
algoritmo proviene del nombre del matemtico Mohamed ibn-Musa al-Khwarizmi que form parte
de la corte real en Bagdad aproximadamente entre los aos 750 a 850 DC. Es fuente adems de la palabra algebra. Enciclopedia Britnica:
Estructura de datos.-
recuperacin eficientes. La estructura de datos ms simple es el arreglo unidimensional (lineal). Enciclopedia de ciencia y tecnologa de McGraw-Hill: Medio para almacenar una coleccin de datos. La ciencia de la computacin es en parte el estudio de los mtodos para usar efectivamente una computadora en la solucin de problemas, o en otras palabras, la determinacin exacta del problema a resolver. Este proceso implica: 1. 2. Comprender el problema. Traducir descripciones vagas, metas y requerimientos contradictorios (y a menudo deseos sin especificar) dentro de una solucin conceptual formulada con precisin con un lenguaje de programacin. Esta solucin generalmente consiste en dos partes: algoritmos y
estructuras de datos.
Relacin con algoritmos. Un algoritmo es una especificacin concisa de un mtodo para resolver un problema. Una estructura de datos puede verse como un conjunto de algoritmos para realizar operaciones sobre los datos que almacena. As, los algoritmos son parte de lo que constituye una estructura de datos. En la construccin de la solucin a un problema, una estructura de datos debe ser elegida de manera que permita que los datos sean manipulados fcilmente de la manera que el algoritmo lo requiere.
Un algoritmo puede requerir colocar datos nuevos en una coleccin existente de los mismos, removerlos o acceder a una coleccin de datos para propsitos especficos. Tipos de datos abstractos (TDA). Un tipo de dato abstracto (TDA), abstract data type (ADT), es un modelo matemtico que puede usarse para capturar lo esencial del dominio de un problema con el fin de traducirlo a un lenguaje de programacin. Es una entidad matemtica que consiste en un conjunto de valores (el conjunto portador) y una coleccin de operaciones que los manipule. Por ejemplo, el tipo de dato abstracto entero consiste de un conjunto portador que contiene los nmero enteros negativos y positivos adems del 0 y una coleccin de operaciones que los manipula como pueden ser la suma, la resta, la multiplicacin, la comparacin de igualdad y la comparacin de orden (Algebra abstracta).
Abstraccin.
Abstraccin es ignorar el detalle de algunas cosas a favor de otras. La abstraccin es importante en la solucin de problemas porque permite a quien los resuelve enfocarse en los detalles esenciales en tanto ignora los no esenciales, simplificando as el problema y concentrando su atencin en aquellos aspectos del mismo que involucran su solucin. Los tipos de datos abstractos son importantes en ciencias de la computacin porque proporcionan una manera clara y precisa para especificar que datos debe manipular un programa (y cmo debe manejarlos) sin considerar los detalles sobre cmo los datos son representados cmo se implementan las operaciones. Una vez comprendidos los tipos de datos abstractos y documentados, sirven como una especificacin que los programadores pueden usar para guiar su decisin sobre la implementacin y operacin de los datos y como un estndar para asegurar la exactitud del programa. Tales especificaciones de los tipos de datos abstractos proporcionan las bases para su realizacin en programas. Los programadores conocen que valores de datos necesitan ser representados, que operaciones sern requeridas y qu limitaciones deben satisfacerse. El estudio cuidadoso del cdigo desarrollado y la apropiada seleccin de pruebas ayudan a asegurar que el programa est correcto. Finalmente las especificaciones de tipos de datos abstractos pueden usarse para investigar y demostrar de los tipos de datos abstractos mismos, llevando a un mejor entendimiento de los programas y finalmente a un software de alta calidad.
mtodos) las operaciones. Los objetos que manejan el mismo tipo de datos y realizan las mismas
operaciones forman una clase. Los valores de datos abstractos estn separados de sus operaciones. Si los valores del conjunto portador de un tipo de dato abstracto se pueden reconceptualizar para incluir no slo valores de datos sino tambin operaciones abstractas, entonces los elementos del conjunto portador se vuelve una entidad que incorpora tanto datos como operaciones, como objetos, y el conjunto portador en s es mucho ms parecido a una clase. El paradigma orientado a objetos puede verse como una extensin del uso de tipos de datos abstractos. Modularidad. Es la propiedad que permite subdividir una aplicacin en partes ms pequeas llamadas mdulos con el fin de hacerla ms comprensible y manejable. Histricamente es una evolucin de la
6 5 4 3 2 1 0 1
. La distancia entre ambos puntos est definida por: [1]
Desarrollar una aplicacin que utilice un TDA que lea los dos puntos, encuentre la distancia entre ambos y muestre la ecuacin de la recta resultante usando el paradigma orientado a objetos. Al principio de esta unidad se estableci que la determinacin exacta de un problema implica, ante todo, la comprensin del mismo. Se puede afirmar que si se es capaz de resolverlo manualmente tal comprensin se ha alcanzado: Solucin (manual):
Pendiente:
Una vez que se entiende el problema el primer paso es la abstraccin del mismo lo que requiere identificar: 1. 2. 3. 4. Que datos son necesarios (entradas). Que datos se esperan en la solucin. Que valores son calculados en los procesos de solucin. Desarrollar el algoritmo que resuelva el problema.
Datos de entrada: P1 y P2 definidos por pares de valores numricos para (x, y) y (x, y)
Recta
Esta es una abstraccin simple, as para el ejemplo considerado la solucin se representa como:
x = 1, y = 1 x = 5, y =5
Recta
d= m=1 y=x
Algoritmos
Recta Propiedades
Nombre X1 X2 Y1 Y2 Tipo de dato Nmero real simple Nmero real simple Nmero real simple Nmero real simple Nombre Distancia Pendiente Ecuacin (Ec)
Mtodos
Tipo de dato Real simple Real simple Cadena Propsito Calcula distancia Obtiene m Ecuacin resultante
En el diseo de clases de este texto seguimos la metodologa propuesta por Deborah Kurata1 As, una vez creada la clase que representar al objeto Recta, el algoritmo general de solucin puede plantearse de la siguiente manera: 1. Leer datos de entrada (X1, Y1, X2, Y2) Asignacin de propiedades.
10
Imports System.Math Public Class CTDA_Recta Private mvarX1 As Single Private mvarX2 As Single Private mvarY1 As Single Private mvarY2 As Single Private mvarm As Single Property X1() As Single Get Return mvarX1 End Get Set(ByVal value As Single) mvarX1 = value End Set End Property Property X2() As Single Get Return mvarX2 End Get Set(ByVal value As Single) mvarX2 = value End Set End Property Property Y1() As Single Get Return mvarY1 End Get Set(ByVal value As Single) mvarY1 = value End Set End Property Property Y2() As Single Get Return mvarY2 End Get Set(ByVal value As Single) mvarY2 = value End Set End Property
P r o p i e d a d e s
11
M t o d o s
Uso en consola:
Imports System.Console Module Module1 Private MiTDA As New CTDA_Recta Sub Main() BackgroundColor = ConsoleColor.White ForegroundColor = ConsoleColor.Black Clear() WriteLine("Punto P1:") Write("X1 = ") MiTDA.X1 = ReadLine() Write("Y1 = ") MiTDA.Y1 = ReadLine() WriteLine() WriteLine("Punto P2:") Write("X2 = ") MiTDA.X2 = ReadLine() Write("Y2 = ") MiTDA.Y2 = ReadLine() WriteLine() WriteLine("RESULTADOS") WriteLine("Distancia = " + MiTDA.Distancia.ToString("n4")) WriteLine("Pendiente m = " + MiTDA.m.ToString("n2")) WriteLine("La ecuacin es:") WriteLine() WriteLine(MiTDA.Ec) ReadKey() End Sub End Module
Ejecucin:
12
El uso de consolas permite una rpida revisin de la solucin que se trata de implementar. Despus de probar con diferentes valores con resultados conocidos, la solucin se transporta fcilmente al entorno Windows.
Para crear la solucin usando las capacidades de VB.NET se puede crear la siguiente forma bsica:
Objetos en esta ventana (valores sugeridos): Objeto (Name) frmTDA_Recta txtX1, txtY1 txtX1, txtY2 btnResult labD, labM Tipo Form Textbox TextBox Buttton Label Propiedades MaximizeBox = False StartPosition = CenterScreen TextAlign = Center TextAlign = Center AutoSize = False Propsito
13
labEc
Label
Mostrar la ecuacin.
Agregar al proyecto la clase TDA desarrollada previamente: Men Proyecto Agregar elemento existente.
Ejecucin:
Public Class frmTDARecta Private MiTDA As New CTDA_Recta Private Sub btnResult_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnResult.Click Try 'Lectura de puntos P1 y P2: MiTDA.X1 = CSng(txtX1.Text) MiTDA.Y1 = CSng(txtY1.Text)
14
Ejercicio #1 para el desarrollo de la competencia especfica: Para un cilindro circular (recto)3 se tienen las frmulas siguientes: Volumen: [1]
rea: [2]
15
Y de [2]
Si h=4yA= Obteniendo el radio de [2]: r = 1, luego el dimetro es 2r = 2 Por ltimo si se conocen los valores de d y de A: Entonces h 4 . Prueba del programa:
16
Solucin para Windows Aprovechando las muchas facilidades de interfaz para el usuario que proporciona VB.NET, una solucin al problema podra verse as: Ventana de base (frmTDACilindro):
Los controles de opciones (RadioButton) tienen asignado un valor numrico consecutivo en su propiedad
(Tag = 1) Tag = 0 en la caja de texto. Altura (Tag = 2) Tag = 1 en la caja de texto del dimetro. Todos tienen su propiedad Chcked en False y
17
estn
contenidos
en
un
GroupBox.
Tag
0 1 2
Cada vez que el usuario selecciona una opcin el valor de la propiedad Tag es asignado a un objeto de tipo entero corto, (iModo), manejando este evento en un solo procedimiento (de evento) y permite conocer que partes del TDA usar.
Public Class frmTDACilindro Private MiTDACil As CTDA_CilindroR 'La clase se importa desde la aplicacin de consola donde fue desarrollada y probada Private iModo As Short Private Sub frmTDACilindro_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 'La carga de la forma establece la primera seleccin y se desencadena el evento: rbVol.Checked = True End Sub Private Sub rbAltura_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles rbAltura.CheckedChanged _ , rbD.CheckedChanged, rbVol.CheckedChanged 'Cualquier evento de seleccin es manejado en este procedimiento Dim oRB As RadioButton = sender If oRB.Checked Then MiTDACil = New CTDA_CilindroR iModo = oRB.Tag SetTextos() btnOK.Enabled = True End If End Sub
As las tres opciones son manejadas en la misma ventana: Caso 1: Altura y dimetro conocidos. Al el seleccionar rea esta opcin, los
objetos de texto para el volumen y son desactivados (propiedad ReadOnly = True) por el mdulo SetTextos. De esta manera, el usuario slo puede ingresar los valores conocidos (propiedades del TDA). El botn mtodos desarrollados en la clase y muestra los resultados faltantes. desencadena los (operaciones)
18
Caso
3:
Dimetro
altura
conocidos.
Private Sub SetTextos() For Each oTexto As Control In Me.Controls If TypeOf (oTexto) Is TextBox Then Dim txt As TextBox = oTexto txt.Clear() txt.ReadOnly = True If iModo = 0 Then txt_h.ReadOnly = False txtD.ReadOnly = False ElseIf iModo = 1 Then txt_h.ReadOnly = False txtArea.ReadOnly = False Else txtD.ReadOnly = False txtArea.ReadOnly = False End If End If Next End Sub
19
Ejercicio #2: Para el cuerpo geomtrico denominado cono circular (recto) se tienen las siguientes frmulas4: [1]
[2]
[3]
[4]
[5]
20
Arreglos. El arreglo es la estructura de datos ms comn y existe desde los primeros lenguajes de programacin. Un arreglo permite almacenar un conjunto de elementos ordenndolos por posicin, generalmente la primera posicin tiene el valor de cero y, normalmente, debe conocerse el nmero de elementos N que se van a almacenar.
0 1 2 N
Posiciones Elementos
Ei
En
El uso de esta estructura requiere reservar ubicaciones de memoria RAM contiguas en tiempo de compilacin y esta asignacin puede ser esttica o dinmica. Dependiendo de cmo sea declarado, un arreglo puede existir (ser accesible) en: Todo el programa. En un mdulo En un procedimiento. de forma esttica no se libera sino hasta que la ejecucin del programa
La memoria asignada
termina de otro modo el arreglo deja de existir al terminar la ejecucin del mdulo o el procedimiento donde fue creado. En VB.NET, un arreglo es una instancia de la clase Array misma que proporciona un conjunto de mtodos tales como ordenacin y bsqueda que en el pasado se tenan que desarrollar. Sin embargo eso no impide que se analicen los diferentes algoritmos para tales procesos. Este lenguaje (y todos los que usan el marco .NET) tienen una clase nueva denominada ArrayList que es un arreglo que obtiene ms espacio de forma dinmica a medida que lo requiere. En situaciones donde no se conoce con exactitud el tamao del arreglo o cuando ste puede cambiar durante el ciclo de vida de un programa un ArrayList puede ser una mejor eleccin que un arreglo simple.
21
tipo entero) y estableciendo que tipo de datos manejar. Esta accin se representa como A[N], a
cada elemento del arreglo se le asigna un valor (del tipo adecuado) usando un apuntador i. Un arreglo de una dimensin se puede declarar a nivel mdulo como: Private Arreglo(), si no se especifica su tamao N, se dice que el arreglo es dinmico y puede modificar su tamao en cualquier parte del mdulo usando la instruccin ReDim. Ejemplo:
Imports System.Console Module Module1 Private Arreglo() As Integer, N As Short Sub Main() ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim i As Short Write("N = ") N = ReadLine() 'Se forma el arreglo, si existiera uno previo ser reemplazado 'El valor de cada uno de sus elementos es cero ReDim Arreglo(N) For i = 0 To N - 1 Write("A[" + i.ToString + "] = ") Arreglo(i) = ReadLine() Next WriteLine() WriteLine("El arreglo es:") WriteLine() For i = 0 To N - 1 Write(Arreglo(i).ToString + " ") Next WriteLine() ReadKey() End Sub End Module
Se puede modificar el tamao de un arreglo sin perder la informacin almacenada en l usando la instruccin Redim Preserve:
Modificando el programa anterior: Imports System.Console Module Module1 Private Arreglo() As Integer, N As Short Sub Main() ForegroundColor = ConsoleColor.Black
22
Ejecucin:
23
Este tipo de arreglos consume ms memoria que los dinmicos. Si A[i] k, donde 0<=i <=N-1 (Tipo de datos) As por ejemplo: Si N = 5, A[N] (3, 5, 7, 1, 2) en VB.NET se puede crear de la manera clsica como: El uso de consola es prctico solo para arreglos pequeos para probar procedimientos bsicos. Listado #1.
Imports System.Console Module Module1 Sub Main() ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim N As Short = 5 Dim A(N - 1) As Short '5 posiciones ya que la primera comienza en cero A(0) = 3 A(1) = 5 A(2) = 7 A(3) = 1 A(4) = 2 WriteLine("El arreglo es:") For i As Short = 0 To N - 1 Write(A(i).ToString + " ") Next WriteLine() ReadKey() End Sub End Module
El mismo programa en las versiones de VB.NET 2008 y posteriores se puede escribir as:
24
El ciclo For-Each itera sobre cada elemento del arreglo comenzando por el primero sin necesidad de apuntadores. mantener
Todas las ejecuciones producen la misma salida: En todos los casos, el arreglo A[N] fue declarado localmente (dentro del procedimiento Sub Main( ) y de forma dinmica. Por tanto existe slo mientras tal procedimiento es ejecutado.
Manejo de diferentes conjuntos de datos sobre un mismo arreglo. En el siguiente cdigo, el arreglo A[ ] es declarado a nivel del mdulo usando adems la palabra
Priivate, lo que significa que el arreglo permanece durante la ejecucin del mdulo y al ser declarado
inicialmente sin dimensin se dice que es un arreglo dinmico. Cada vez que se establece un valor numrico para N el arreglo se crea usando ReDim que adems inicializa todos sus elementos en cero.
25
Para el anlisis de algoritmos que involucran arreglos de un tamao relativamente grande, el uso de consolas resulta bastante tedioso. Es conveniente crear una forma general que maneje arreglos de una manera eficiente y permita desarrollar y probar diferentes algoritmos. Forma bsica para arreglos de una dimensin:
5
6
GetLowerBound(k) regresa el lmite inferior del arreglo k = 0 para arreglos de una dimensin. GetUpperBound(k) el lmite superior de un arreglo, k =0 para renglones y k = 1 para columnas en una matriz.
26
Descripcin de la aplicacin: Permite establecer el valor del tamao del arreglo (N). Al aceptarlo ste ser creado y se prepara su interfaz para la asignacin de sus valores.
Los controles de esta seccin estn contenidos en un GroupBox cuya propiedad Name se establece como GpoN. Un control numrico (NumericUpDown) con propiedades Maximum = 200 y Minimum =
27
Multiline
establecida
en
True.
SrollBars
Both,
SaveFD.- Control SaveFileDialog, defaultExt = dat, Filter = Archivos de datos (*.dat)|*.dat. OpenFD.- Control OpenFileDialog con las mismas propiedades Filter y defaultExt anteriores y la propiedad FileName = (nada)
La primera fase de desarrollo debe permitir crear arreglos, asignar sus valores (numricos), guardarlo y recuperarlo Este es el primer cdigo a escribir.
Public Class frmArray Private Arreglo() As Integer, N Private Sub frmArray_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim sRuta As String = My.Application.Info.DirectoryPath + "\Arreglos" 'Si esta ruta no existe, se crea If Not My.Computer.FileSystem.DirectoryExists(sRuta) Then My.Computer.FileSystem.CreateDirectory(sRuta) End If 'Ruta inicial para los cuadros de dilogo de archivos SaveFD.InitialDirectory = sRuta OpenFD.InitialDirectory = sRuta End Sub
28
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click CreaArreglo() End Sub
En este procedimiento se asigna el valor de N, se forma un arreglo nuevo y se prepara DGVA para representarlo y manejarlo.
Private Sub CreaArreglo() N = NumN.Value ReDim Arreglo(N) With DGVA .RowCount = 1 'Siempre un slo rengln .ColumnCount = Arreglo.GetUpperBound(0) 'Columnas = Tamao del arreglo For Each Kol As DataGridViewColumn In DGVA.Columns Kol.HeaderText = Kol.Index 'Posicin Kol.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells 'Autoajuste de celdas Kol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter 'Alineado al centro Next End With Valores() btnSave.Enabled = True End Sub
Private Sub Valores() 'Muestra el arreglo en DGVA Dim i As Integer For i = 0 To N - 1 DGVA.Rows(0).Cells(i).Value = Arreglo(i) Next End Sub
Si el valor ingresado en la celda actual es numrico lo convierte a tipo entero de otro modo lo establece en cero.
Private Sub DGVA_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGVA.CellEndEdit If IsNumeric(DGVA.CurrentCell.Value) Then Arreglo(e.ColumnIndex) = CInt(DGVA.CurrentCell.Value) Else MsgBox("Valor no permitido", MsgBoxStyle.Exclamation) DGVA.CurrentCell.Value = 0 End If End Sub
Guardar el arreglo actual: (Doble clic en el botn para generar la plantilla del procedimiento de evento)
29
Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click If OpenFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim FM As Short = FreeFile() 'Abre el archivo para lectura secuencial FileOpen(FM, OpenFD.FileName, OpenMode.Input) 'Lee el primer valor (N) N = LineInput(FM) NumN.Value = N CreaArreglo() 'Asigna sus valores secuencialmente: Dim x As Integer For i As Integer = 0 To N - 1 x = LineInput(FM) Arreglo.SetValue(x, i) 'Equivale a Arreglo(i) = x Next FileClose(FM) Valores() End If End Sub
Aplicacin de arreglos.
Ejemplo: La compresin de un arreglo a veces implica eliminar los elementos que se repiten y mostrar los valores que permanecen en la misma secuencia. Si el arreglo es: 15 9 10 4 15 10 3 4 15 20
30
algoritmo en un lenguaje natural (espaol, por ejemplo) separando los pasos consecutivos que han de seguirse usando expresiones algortmicas para denotar el cmo hacerlo de manera que se pueda resolver cualquier problema similar. Resolver el problema directamente usando papel y lpiz para poder tener una base de comprobacin a la solucin. Arreglo comprimido ( )
Private Sub btnComprimir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnComprimir.Click Dim i, j, m As Integer m = 0 '...[1] '[2]
31
Usando un arreglo para los coeficientes ai, encontrar el valor de una expresin y diferentes valores de X (X1, X2, ) Solucin: Sea
32
Lo primero que debe plantearse es que tamao de arreglo usar. Una vez que los coeficientes son asignados usando los valores de sus posiciones se puede resolver la expresin para valores de X dados. La solucin puede presentarse como:
Algoritmo.
1. 2. 3. 4. 5. Establecer el tamao del arreglo en base al grado del polinomio (m). N m + 1. Crear el arreglo y asignar los coeficientes. A[i] ai Inicializar el valor de la expresin: P 0 Leer un valor para X Iterar sobre el arreglo para cada valor de X (Si X > 0) (A[i], i 0, 1, , N) km-i P P + A([i]*X k 6. Mostrar resultado.
Private Sub btnPoli_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPoli.Click Dim X As Integer = Val(InputBox("Valor de X", "Datos", "1")) If X > 0 Then
33
Ejercicios propuestos: 1.- Un nmero entero positivo en base decimal se puede convertir a su base binaria u octal con divisiones sucesivas entre la base (2 u 8) y acumulando los residuos en un arreglo hasta que el cociente se cero. Por ejemplo: Sea Nmero 1024 Dividendo 1024 512 256 178 64 32 16 8 4 2 1 Divisor 2 2 2 2 2 2 2 2 2 2 2 Cociente 512 256 128 64 32 16 8 4 2 1 0 Residuo 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0
Arreglo de residuos 0 0 0 0 0 0 0 0 0 0
1
0 0 0 0 0 0 0 0 0
2
0 0 0 0 0 0 0 0
3
0 0 0 0 0 0 0
4
0 0 0 0 0 0
5
0 0 0 0 0
6
0 0 0 0
7
0 0 0
8
0 0
9
1
10
El nmero binario resultante se obtiene leyendo el arreglo de derecha a izquierda: 10000000000 Escribir el procedimiento de evento para esta tarea (Base 2 u 8). Sugerencia:
34
RadioButtons
rbBin, propiedad Checked = True rbOctal. Dado que estas conversiones de base son utilizadas frecuentemente en otras soluciones es conveniente crear este procedimiento en una funcin pblica dentro de un mdulo: Agregar un mdulo a esta aplicacin (Men Proyecto Agregar mdulo) dndole un nombre a ste:
Module ModMisMetodos Public Function BaseN(ByVal Num As Long, ByVal Base As Short, ByRef Arr() As Object) As String Dim Salida() As Char Dim N As Short = 16 Dim Cociente As Long = 0, P As Short = -1, Res As Short ReDim Salida(N) 'Solucin al problema: Salida() es un arreglo temporal de tipo Cdigo a desarrollar Do '1.- Obtener el cociente '2.- Obtener el residuo y 'guardarlo en Salida(P) '3.- Num = Cociente '4.- Repetir desde el paso 1 hasta 'que el cociente sea cero. Loop Until Cociente = 0 Dim sTemp As String = "" 'Se lee el arreglo resultante 'de derecha a izquierda para 'formar la cadena de salida For i = P To 0 Step -1 sTemp += Salida(i) Next 'Ajusta el tammao del arreglo Arr() 'conservando el valor de sus elementos ReDim Preserve Arr(P + 1) Return sTemp End Function End Module
La funcin BaseN recibe la informacin necesaria para convertir un nmero decimal a su equivalente en binario u octal.
35
Num
Base Arr()
Private Sub btnBaseN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBaseN.Click Dim Numero As Long Dim Base As Short = 2 'Base 2 u 8 Numero = Val(InputBox("Nmero decimal", "Cambio de base", "0")) txtSol.Clear() If Numero > 0 Then ReDim Arreglo(64) 'Tamao inicial del arreglo Dim sCurrSel As String = rbBin.Text If rbOctal.Checked Then Base = 8 sCurrSel = rbOctal.Text End If txtSol.Text = Numero.ToString + " -->" + BaseN(Numero, Base, Arreglo) + " (" + sCurrSel + ")" N = Arreglo.GetUpperBound(0) NumN.Value = N CreaArreglo(False) Else MsgBox("Valor no permitido", MsgBoxStyle.Information) End If End Sub
Ejecucin8 :
36
2.- Problema de caracteres. La clase ArrayList El uso de instrucciones ReDim y ReDim Preserve consume recursos de la computadora, adems debe incluirse cdigo cuando debe modificarse el tamao de un arreglo. La solucin a este problema es el uso de un tipo de arreglo que se dimensiona automticamente cuando alcanza su lmite de almacenamiento fsico. Este arreglo se llama ArrayList y forma parte de la coleccin del espacio de nombres en System.Collections en la librera del marco .NET. Un objeto ArrayList tiene la capacidad de almacenar su tamao como una propiedad cuyo valor inicial es 16. Cuando el nmero de elementos en un ArrayList alcanza este lmite, la propiedad Capacidad agrega otros 16 elementos. El uso de un ArrayList en situaciones donde el nmero de elementos puede crecer o disminuir, es ms eficiente que usar comandos Redim o Redim Preserve en arreglos estndar.
Estos son algunos de los mtodos y propiedades que incluye la clase ArrayList:
Add() AddRange Capacity Clear() Contains() CopyTo() Count GetEnnumerator GetRange() IndexOf() Insert
Agrega un elemento a la lista Agrega los elementos de una coleccin al fina de un ArrayList Almacena el nmero de elementos que un ArrayList puede manejar Elimina todos los elementos del ArrayList Determina si un tem especfico existe en el arreglo Copia el ArrayList un segmento de ste a un arreglo Es el nmero de elementos actualmente en la lista Regresa un enumerador para iterar sobre un ArrayList Devuelve un subconjunto del ArrayList como otro ArrayList Devuelve el ndice de la primera ocurrencia de un tem especfico Inserta un elemento en un ndice especificado
37
Ejemplo uso.- Se desea ayudar al profesor con el manejo de su grupo. Donde se requiere un objeto
La lista del curso es una Coleccin de alumnos que luego se pasa a un ArrayList para su mejor manejo. Crear una clase que agregue algunos mtodos al ArrayList para: Ubicar al primer alumno de la lista con mayor y menor calificacin. Mostrar el promedio general del grupo. Crear una lista de alumnos aprobados y otra de alumnos reprobados y mostrar sus promedios. La forma para esto puede ser como se muestra:
38
Objetos requeridos (Por secciones): GroupBox (Contenedor GpoAlumno): txtApe =Upper) txtNom (igual a la anterior) NumCalif =100) btnOK (Button). txtLoc (igual las anteriores) btnFind (Button ) (NumericUpDown Maximum (TextBox, CharacterCasing
DGV (DataGridView con tres columnas de las cuales la tercera es numrica sin decimales) btnToArrayList Botones btnSave y btnOpen para serializar y deserializar la coleccin
9
(opcionales).
Francesco Balena. Programming Microsoft Visual Basic 2005: The Languaje. Microft Press.
39
DGVAL (DataGridViewCol con dos columnas la ltima de las cuales es numrica sin decimales). DGVR (copia de la anterior). btnMayor btnMenor (Button) (Button)
labProm (Label con BorderStyle = Fixed3D y texto 0.0 alineado a la derecha, AutoSize = False) labProm2 (copia de la anterior).
btnRepro (Button) btnApro (Button) labCalMayot (Label, BorderStyle = Fixed3D, AutoSie =False) labCalMento (copia de la anterior) La ventana de propiedades de un DataGridView se abre con un clic en la esquina superior derecha:
El las
valor
numrico
de
la
DefaultCellStyle.
Funcionamiento:
40
Luego se llena un ArrayList con el nombre completo del alumno y su calificacin DGVAL
El botn Selecciona de la lista anterior aquellos alumnos con calificacin menor a 70 (calificacin reprobatoria y los muestra en DGVR.
10
En este ejemplo no se agregaron botones para edicin o para eliminar algn objeto de la coleccin. Puede
agregarlos si lo desea.
41
El botn Hace lo mismo pero para los alumnos que aprobaron el curso (Calif >=70).
42
43
Forma (frmArrayList):
Public Class frmArrayList Private ColDeAl As Collection, Alumno As CAlumno Private ElArregloL As ArrayList, ObjetoArr As New CMiListaArreglo Public Sub New() ' Llamada necesaria para el Diseador de Windows Forms. InitializeComponent() ' Agregue cualquier inicializacin despus de la llamada a InitializeComponent(). Dim sRuta As String = My.Application.Info.DirectoryPath + "\Colecciones" If Not My.Computer.FileSystem.DirectoryExists(sRuta) Then My.Computer.FileSystem.CreateDirectory(sRuta) End If 'Solo en caso de implementar serializacin (Filter Archivos binarios (*.bi) SaveFD.InitialDirectory = sRuta OpenFD.InitialDirectory = sRuta End Sub Private Sub frmArrayList_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ElArregloL = New ArrayList ColDeAl = New Collection End Sub
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click On Error GoTo Repetido Alumno = New CAlumno With Alumno .Apellido = txtApe.Text.Trim .Nombre = txtNom.Text.Trim .Calif = NumCalif.Value End With 'El nombre completo del alumno se toma como clave, lo que evita que se dupliquen 'en la coleccin ColDeAl.Add(Alumno, Key:=Alumno.MiNombre) AddToGrid(Alumno, DGV) txtNom.Clear() txtApe.Clear() txtApe.Focus() Exit Sub Repetido: If Err.Number = 457 Then MsgBox("Ese alumno ya est en la coleccin", MsgBoxStyle.Information) Resume Next Else
44
Private Sub btnToArrayL_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnToArrayL.Click If ColDeAl.Count > 0 Then For Each A As CAlumno In ColDeAl ElArregloL.Add(A) ToGrid2(A, DGVAL) Next labProm.Text = ObjetoArr.Promedio(ElArregloL).ToString("N1") End If End Sub
Private Sub btnFind_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFind.Click Try Dim sAlumno As String = txtLoc.Text.Trim If sAlumno.Length > 0 Then If ColDeAl.Contains(sAlumno) Then MsgBox("Ese alumno s est en la coleccin", MsgBoxStyle.Information) Else MsgBox("Ese alumno no est en la coleccin", MsgBoxStyle.Information) End If
45
Arreglos de dos dimensiones. Un arreglo de dos dimensiones (matriz) es un objeto (del tipo Array) que tiene N renglones y M columnas. En lgebra lineal una matriz es simplemente un arreglo rectangular de elementos y se dice que su orden es N x M. A(N, M) Y cada elemento se indica por A(i, j) donde 0 < = i < = N y 0 < = j < = M.
46
En VB.NET para crear arreglos con dos dimensiones se usa la instruccin Dim Matriz( , ) para su manejo dinmico. Una vez conocidos N y M se forma el arreglo:
Dim Matriz(N M, ) As [Tipo] crea una matriz A(N, M) en donde (al igual que en los arreglos de una
dimensin) el primer rengln y la primera columna tienen el ndice 0. As: N=3 y M = 3 0 0 1 2 1 1 1 1 5 0 1 2 2 2 2
Manejo de matrices en VB.NET. Crear un proyecto nuevo y cargar el mdulo desarrollado anteriormente:
47
Elementos de la forma:
(NumericIpDown) de nombre NumN. Crear primero este control y despus copiarlo y pegarlo en la
Valor 10 2 Center
48
Tres objetos del tipo DataGridViw en donde primero se agrega el primero con el nombre DGVA, se establecen sus propiedades como se indica en la tabla. Luego se copia (al portapapeles) y se pega modificando sus nombres a DGVB y DGVR. ste ltimo cambia su propiedad ReadOnly
True.
Propiedades comunes de los controles DataGridView. Propiedad AllowUserToAddRows AllowUserToResizeRows AutCellsColumnMode MultiSelect Tag11 Valor False False AllCells False En esta ventana se podrn probar
diferentes algoritmos que muestran el manejo de este tipo de arreglos. Se podrn guardar en archivos y recuperarse
en otro momento. A para DGVA, B para DGVB Esta forma manejar tres matrices: btnSuma btnProd btnInvA A[N, M), B([M, K) y R[ , ] cuyo orden depender del resultado de la operacin que se realice. Suma Multiplicacin Inversa Otros problemas a resolver.
GroupBox
Name = GpoOp Enabled = False
btnGuardar btnAbrir
11
Sin comillas.
49
Operaciones con matrices. Suma de dos matrices (A + B).- Esta operacin slo est definida para matrices del mismo orden, esto es, con el mismo nmero de renglones y columnas y genera otra matriz (la suma) del mismo orden. Cada elemento de la matriz resultante se obtiene por:
Por ejemplo:
12
Es decir, cada elemento de la suma se obtiene sumando los elementos correspondientes en A y B en sus respectivas posiciones. Producto de dos matrices A x B. El producto de dos matrices A y B slo est definido si el nmero de renglones de B es igual al nmero de columnas de A.
Por ejemplo:
Funcionalidad de la forma: En todos los problemas desarrollados a lo largo de este texto se guardarn los datos en archivos que se localizarn siempre en una carpeta especialmente creada dentro del directorio donde reside
12
Es matriz resultante.
50
El siguiente procedimiento ajusta las propiedades de los controles de datos (DataGridView) para usarlos tanto pata ingresar los datos de las matrices A y B como para mostrar resultados en R: El procedimiento CreaGrid recibe por referencia13 el control que se va modificar (DataGridView) as como el nmero de renglones y columnas requeridos; Se pasan como parmetros como ElGrid ,
iRows,e iCols. De esta manera opera sobre los controles DGVA, DGVB y DGVR.
El procedimiento VerMatriz cualquier matriz (LaMatriz) en uno de los DatagridView (ElGrid) de la forma.
Private Sub CreaGrid(ByRef ElGrid As DataGridView, ByVal iRows As Short, ByVal iCols As Short) With ElGrid .RowCount = iRows .ColumnCount = iCols For Each Kol As DataGridViewColumn In ElGrid.Columns Kol.HeaderText = Kol.Index Kol.DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopCenter Next End With End Sub Private Sub VerMatriz(ByRef LaMatriz(,) As Single, ByRef ElGrid As DataGridView) Dim i, j As Short For i = 0 To LaMatriz.GetUpperBound(0) 'Limite de renglones For j = 0 To LaMatriz.GetUpperBound(1) 'Limite de columnas ElGrid.Rows(i).Cells(j).Value = LaMatriz(i, j) Next Next End Sub
13
51
Private Sub btnNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNew.Click 'Prepara la forma para otras matrices DGVA.RowCount = 0 DGVA.ColumnCount = 0 DGVB.RowCount = 0 DGVB.ColumnCount = 0 DGVR.RowCount = 0 DGVR.ColumnCount = 0 GpoOp.Enabled = False ReDim MatA(0, 0), MatB(0, 0), MatR(0, 0) End Sub
Hasta este punto, al ejecutar la aplicacin debe verse as al hacer clic en [Aceptar]:
Validacin de los datos de entrada: Todo valor ingresado debe ser numrico. El procedimiento de evento opera sobre DGVA y/o DGVB y asigna el valor ingresado a la matriz que representa (A B).
Private Sub DGVA_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGVA.CellEndEdit _ , DGVB.CellEndEdit Dim ElGrid As DataGridView = sender If Not IsNumeric(ElGrid.CurrentCell.Value) Then MsgBox("Valor no permitido", MsgBoxStyle.Exclamation) ElGrid.CurrentCell.Value = 0
52
Procedimientos para guardar y abrir matrices (en y desde archivos).- Las matrices pueden almacenarse tambin en archivos secuenciales. Ya que el cdigo necesario para guardar las matrices A y B es repetitivo, se crea un procedimiento comn:
Private Sub SaveMatrix(ByRef LaMatriz(,) As Single, ByVal NA As Short) Dim i, j As Short For i = 0 To LaMatriz.GetUpperBound(0) For j = 0 To LaMatriz.GetUpperBound(1) PrintLine(NA, LaMatriz(i, j)) Next Next End Sub
Entonces
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click Try If SaveFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim NA As Short = FreeFile() FileOpen(NA, SaveFD.FileName, OpenMode.Output) 'Primero se almacena el orden de la matriz PrintLine(NA, N) PrintLine(NA, M) PrintLine(NA, K) 'Luego cada matriz en recorrido por renglones SaveMatrix(MatA, NA) SaveMatrix(MatB, NA) FileClose(NA) MsgBox("Matrices guardadas", MsgBoxStyle.Information) End If Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Information) FileClose() End Try End Sub
Private Sub btnAbrir_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAbrir.Click Try Dim i, j As Short If OpenFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim NA As Short = FreeFile() FileOpen(NA, OpenFD.FileName, OpenMode.Input) 'Leer el orden de las matarices N = LineInput(NA) M = LineInput(NA) K = LineInput(NA)
53
Probar con diferentes valores en diferentes matrices estos procedimientos. Suma de A + B: Con el fin de generalizarlo y poder usarlo en otras aplicaciones, este procedimiento se crea en el mdulo:
Public Sub SumaAB(ByRef A(,) As Single, ByRef B(,) As Single, ByRef R(,) As Single) Dim i, j As Short For i = 0 To A.GetUpperBound(0) For j = 0 To A.GetUpperBound(0) R(i, j) = A(i, j) + B(i, j) Next Next End Sub
Todas las matrices se pasan por referencia para que los cambios en ellas se reflejen en la ventana desde donde se invoca el procedimiento. En la forma principal:
Private Sub btnSuma_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSuma.Click ReDim MatR(N - 1, M - 1) SumaAB(MatA, MatB, MatR) CreaGrid(DGVR, N, M) VerMatriz(MatR, DGVR) End Sub
Prueba:
54
Producto A x B. Al igual que la suma, este procedimiento se crea en el mdulo para su uso en el futuro.
Public Sub ProdAB(ByRef A(,) As Single, ByRef B(,) As Single, ByRef R(,) As Single) Dim i, j, c As Short For i = 0 To A.GetUpperBound(0) For c = 0 To B.GetUpperBound(1) For j = 0 To A.GetUpperBound(1) R(i, c) += A(i, j) * B(j, c) Next Next Next End Sub
Private Sub btnProd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProd.Click ReDim MatR(N - 1, K - 1) ProdAB(MatA, MatB, MatR) CreaGrid(DGVR, N, K) VerMatriz(MatR, DGVR) End Sub
55
Problemas: 1.- Transpuesta. La transpuesta de una matriz se obtiene intercambiando renglones por columas:
Su transpuesta es:
2.- La inversa de una matriz A(N, M) en donde N = M y denotada como A -1 es una matriz del mismo orden tal que:
56
Investigar diferentes mtodos para encontrar la inversa de una matriz A. Implementar uno en el Mdulo. La inversa (si existe) debe guardarse en el arreglo B, de manera que se pueda verificar por medio del producto AxB.
57
3.- Aplicaciones: Modelo de Regresin Lineal Mltiple. En estadstica, cuando se considera que el resultado de alguna variable (Y) depende del valor de otros valores (X j) es posible desarrollar un modelo que explique esa relacin. El modelo ms sencillo se conoce como el modelo de regresin lineal mltiple. Definido como:
Y un mtodo muy efectivo para obtener esta ecuacin a partir de un conjunto de observaciones (en algn experimento) es usando matrices: Ejemplo: Se tienen los siguientes datos (observados): Y 3 1 8 3 5 X1 3 1 5 2 4 X2 5 4 6 4 6
El mtodo14 consiste en crear una matriz X con los datos Xi,j agregando una columna inicial cuyos valores sern siempre 1. Matriz X: 1 1 1 1 1 3 1 5 2 4 5 4 6 4 6
14
58
Luego el vector Xy de Xt Y:
59
Descripcin de la forma: El proyecto de denomin RegresinLinealMultiple, la forma de denomin frmRLM y se import el mdulo ModMisMetodos desarrollado en la aplicacin previa.
15
Llevar a este programa al mdulo con las operaciones de multiplicacin, inversa de una matriz desarrollado
en el programa anterior.
60
Control DataGridView: Nombre= DGVX Mismas propiedades que el anterior ms ReadOnly = True Muestra el arreglo X.
61
Es un TextBox con nombre txtEc, TextAlign = Center y ReadOnly = True. Sirve para mostrar la ecuacin resultante.
1. 2. 3. 4.
btnArreglos.- Muestra los valores de los arreglos X y Y. (Enabled = False). btSave.- Guarda los datos iniciales (los arreglos X y Y). Enabled = False btnOpen.- Recupera el archivo de datos. btnNew.- Prepara la forma para nuevos datos. btnStart.- Inicia el proceso de clculos. Enabled = False. btnClose.
Dilogos para guardar y abrir archivos: DefaultExt = dat, Filter = Archivos de datos (*.dat)|*.dat. Con los nombres que aparecen en la imagen.
Operacin: Se ingresa el nmero de datos observados y el total de variables x. 5 observaciones con dos variables X. Al aceptar se crean los arreglos iniciales y se preparan los DataGridView: Se asignan los valores de 1 en la primera colimna (que adems se establece como slo lectura). Aqu se capturan los datos.
62
Cuando los datos son ingresados stos son asignado a los arreglos X Y usando el evento CellEndEdit. As, cuando se selecciona se mostrarn los
Se declaran loa arreglos ms importantes y el constructor de la forma, crea un directorio por defecto para guardar datos:
Public Class frmRLM Private X(,), XX(,) As Single Private Y(), XY(), B() As Single Private N, M As Integer Public Sub New() ' Llamada necesaria para el Diseador de Windows Forms. InitializeComponent() ' Agregue cualquier inicializacin despus de la llamada a InitializeComponent(). Dim sRuta As String = My.Application.Info.DirectoryPath + "\RLM" If Not My.Computer.FileSystem.DirectoryExists(sRuta) Then My.Computer.FileSystem.CreateDirectory(sRuta) End If SaveFD.InitialDirectory = sRuta OpenFD.InitialDirectory = sRuta End Sub
Aqu se dimensionan algunos de los arreglos y se forman los DataGridView para visualizarlos y para capturar los datos:
Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click With DGV N = NumN.Value M = NumM.Value .RowCount = N .ColumnCount = M + 2 ReDim X(N - 1, M), Y(N - 1) Dim i, j As Integer For i = 0 To X.GetUpperBound(0) X(i, 0) = 1 Next For j = 0 To DGV.ColumnCount - 2 .Columns(j).HeaderText = "X" + j.ToString .Columns(j).DefaultCellStyle.Alignment = DataGridViewContentAlignment.TopRight
63
Cuando se tienen los arreglos iniciales, pueden guardarse: Los datos se almacenan en un archivo secuencial en e siguiente orden: 1. 2. 3. Valores de N y M. El arreglo X. El arreglo Y.
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click If SaveFD.ShowDialog = Windows.Forms.DialogResult.OK Then Try Dim NA As Short = FreeFile() FileOpen(NA, SaveFD.FileName, OpenMode.Output) PrintLine(NA, N) PrintLine(NA, M) Dim i, j As Integer For i = 0 To X.GetUpperBound(0) 'se omite la 1a columna For j = 0 To X.GetUpperBound(1) PrintLine(NA, X(i, j)) Next Next For i = 0 To Y.GetUpperBound(0) PrintLine(NA, Y(i)) Next FileClose(NA) MsgBox("Arreglos guardados", MsgBoxStyle.Information) Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Exclamation) FileClose() End Try End If End Sub
Los datos se leen en la misma secuencia en que se guardaron y se invoca al procedimiento del botn Aceptar para crear los arreglos y formar los DataGridView iniciales. Al leer los datos, stos son asignados a sus arreglos y mostrados en DataGridView de datos (DGV).
Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click If OpenFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim NA As Short = FreeFile() FileOpen(NA, OpenFD.FileName, OpenMode.Input) N = LineInput(NA)
64
Private Sub btnArreglos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnArreglos.Click VerArreglo(DGVX, X) VerVector(DGVY, Y) btnSave.Enabled = True btnStart.Enabled = True End Sub Private Sub VerArreglo(ByRef ElGrid As DataGridView, ByRef Arreglo(,) As Single) Dim i, j As Integer For i = 0 To Arreglo.GetUpperBound(0) For j = 0 To Arreglo.GetUpperBound(1) ElGrid.Rows(i).Cells(j).Value = Arreglo(i, j) Next Next End Sub Private Sub VerVector(ByRef ElGrid As DataGridView, ByRef MiArr() As Single) Dim i, j As Integer For i = 0 To MiArr.GetUpperBound(0) ElGrid.Rows(i).Cells(0).Value = MiArr(i) Next End Sub
Inicia todos los procedimientos enfocados a resolver el problema: Obtener la ecuacin de ajuste. 1. 2. 3. 4. 5. 6. Crea la transpuesta de X. La multiplica por X y por Y para obtener XX y Xy. Obtiene la inversa de XX. Multiplica la inversa por el arreglo Xy para obtener el arreglo de resultados, B. Forma los DatagridVew necesarios para mostrar resultados intermedios y el resultado final el arreglo B. Obtiene la ecuacin resultante.
65
Se asume que los procedimientos utilizados ya fueron creados y probados en la aplicacin anterior. En caso de que falte alguno (por ejemplo la multiplicacin de un arreglo de dos dimensiones por uno de una un vector, habr que desarrollarlo en ese mdulo - ProdMatArr(InvXX, XY, B) Realiza la multiplicacin de la inversa de XX por el vector XY y el resultado lo coloca en B.
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click 'Transpuesta: Dim XT(M - 1, N - 1) As Single ReDim XX(M, M) Dim InvXX(M, M) As Single ReDim B(M) TranspuestaA(X, XT) 'Producto Transpuesta * arreglo X para obtener XX. ProdAB(XT, X, XX) ReDim XY(M) 'Transpuesta * Y para obtener Xy ProdMatArr(XT, Y, XY) DGVXX.RowCount = M + 1 DGVXX.ColumnCount = M + 1 DGVInv.RowCount = M + 1 DGVInv.ColumnCount = M + 1 'Clculo de la inversa de XX. InversaA(XX, InvXX) VerArreglo(DGVXX, XX) VerArreglo(DGVInv, InvXX) DGVXy.RowCount = M + 1 DGVXy.ColumnCount = 1 DGVB.ColumnCount = 1 DGVB.RowCount = M + 1 'Producto de Inversa * XY para obtener el arreglo B ProdMatArr(InvXX, XY, B) VerVector(DGVXy, XY) VerVector(DGVB, B) 'Mostrar el resultado. ShoResult() End Sub Private Sub ShoResult() Dim sEc As String = "Yc = " + B(0).ToString("N2") Dim i As Short For i = 1 To B.GetUpperBound(0) If Math.Sign(B(i)) = 1 Then sEc += " + " End If sEc += B(i).ToString("N2") + "X" + i.ToString Next txtEc.Text = sEc End Sub
Si se completa esta aplicacin, la competencia especfica de esta unidad queda suficientemente acreditada.
66
2 Recursividad.
Competencia especifica.- Comprender y aplicar la recursividad como herramienta de programacin en el manejo de las estructuras de datos.
DEFINICIN.- Se denomina recursividad a la capacidad de un procedimiento de llamarse a s mismo. Es el nombre que se da a la tcnica de definir un conjunto o un proceso en trminos de s mismo 16. La funcin factorial cuyo dominio son los nmeros naturales puede ser definida recursivamente como:
En donde Factorial(N) est definida en trminos de Factorial(N-1) que luego se vuelve en trminos de Factorial(N-2), etc., hasta que finalmente se alcanza Factorial (0) y su valor es entonces 1. Una definicin recursiva de un conjunto de procesos debe contener una definicin explcita para los valores particulares de sus argumentos de otro modo la definicin podra nunca converger. La idea bsica es definir una funcin para todos sus argumentos de una manera constructiva usando induccin. El valor de una funcin para un valor especfico de su argumento puede calcularse en un nmero finito de pasos usando la definicin recursiva donde en cada paso de la recursin se acerca ms a la solucin. Ejemplo 1:
Imports System.Console Module Module1 Sub Main() ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim N As Integer, F As Long Write("N = ") N = ReadLine()
16
67
Este tipo de recursin de conoce como funcin definida recursivamente ( funciones recursivas
primitivas). Un segundo tipo de recursin es el uso recursivo de un procedimiento (recursin no primitiva). Un ejemplo de esta recursin es la funcin de Ackerman, la cual se define como 1:
Ejemplo 2.
Imports System.Console Module Module1 Sub Main() BackgroundColor = ConsoleColor.White ForegroundColor = ConsoleColor.Black Clear() Dim N, M As Short Write("N =") N = ReadLine() Write("M = ") M = ReadLine() Write("Valor de la funcin A =") WriteLine(Ackerman(M, N)) ReadKey() End Sub Private Function Ackerman(ByVal M As Short, ByVal N As Short) As Integer If M = 0 Then Ackerman = N + 1 ElseIf N = 0 Then Ackerman = Ackerman(M - 1, 1) Else
68
Ejemplo 3. Escribir una funcin recursiva para convertir enteros decimales a su representacin en otra base (B) por medio de divisiones sucesivas. El nombre de esta funcin debe ser CONVERT con dos parmetros formales Nmero y Base donde el primero denota al entero que se va a convertir y el segundo es la base. El resultado se regresa como una cadena (texto). Por ejemplo, para encontrar la representacin en base 6 de 184 implica que se dividir repetidamente entre 6 y los residuos obtenidos son concatenados: 184 6 4 306 0
56 5 El resultado es entonces 504
MaximizeBox = False
69
Public Class frmConvert Private Numero, Base As Integer Private Sub btnConvert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConvert.Click If IsNumeric(txtNum.Text) Then Numero = CInt(txtNum.Text) Base = NumBase.Value labResult.Text = StrReverse(Convert(Numero, Base)) End If End Sub Private Function Convert(ByVal N As Integer, ByVal B As Integer) As String Dim Cociente, Residuo As Integer Cociente = Math.DivRem(N, B, Residuo) If Cociente > 0 Then Convert = Residuo.ToString + Convert(Cociente, Base) Else Convert = (N Mod B).ToString End If End Function Private Sub btnNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNew.Click txtNum.Clear() labResult.Text = "" txtNum.Focus() End Sub End Class
Ejercicios: 1.- El mximo comn divisor de dos enteros se define como (Algoritmo de Euclides):
Donde MOD (m, n) es el mdulo aritmtico17, esto es, el residuo de dividir m n. Escribir la funcin recursiva para este caso.
17
70
2.- Escribir una funcin recursiva para calcular la raz cuadrada de un nmero. Leer una tripleta de de nmeros N, A y E, donde N es el nmero para el cual debe encontrarse la raz cuadrada, A es una aproximacin de la raz cuadrada y E es el error permitido en el resultado.
Usar las siguientes tripletas de nmeros para pruebas: N 2 3 8 225 A 1.0 1.5 2.5 14.2 E 0.001 0.001 0.001 .001
3.- En muchas aplicaciones es necesario conocer el nmero de particiones diferentes de un entero N dado, es decir, de cuantas formas diferentes se puede expresar a N como una suma de sumandos enteros. Si se denota como QMN al nmero de formas en las cuales un entero M puede ser expresado como una suma, cada uno de estos sumandos no es mayor que N, particiones de N pude definirse en trminos de la siguiente funcin: entonces el nmero de
71
72
3 Estructuras Lineales.
Competencia especifica.- Conocer, Identificar y aplicar as estructuras no lineales en la solucin de problemas del mundo real.
LISTAS. Lista Ligada Simple.- Coleccin de una clase de objetos llamados nodos. Cada nodo est ligado a su nodo sucesor en la lista usando una referencia (apuntador). Un nodo consiste en un campo para almacenar datos y el campo para la referencia del nodo (apuntador liga).
Encabezado
Alicia
Juan
Olga
Nada
El arreglo es la estructura natural que se usa cuando se trabaja con listas. Los arreglos proporcionan un acceso rpido a los elementos almacenados y se puede iterar fcilmente sobre ellos. No obstante, el arreglo no es la estructura perfecta ya que la bsqueda de un tem en un arreglo desordenado puede tomar tiempo ya que deben visitarse cada uno de lo elementos del arreglo. Los arreglos ordenados son mucho ms eficientes para las bsquedas, pero las inserciones y remociones toman ms tiempo porque deben cambiarse los elementos hacia arriba hacia abajo para obtener el espacio para una insercin o eliminar espacio en una remocin. Adems en un arreglo ordenado debe buscarse el espacio apropiado para insertar un elemento. La mayor diferencia entre un arreglo y una lista ligada es que mientras que en arreglo los elementos se referencian por su posicin (un ndice) los elementos de una lista ligada lo hace por una referencia (apuntador) a otros elementos en el arreglo, as se dice que Juan sigue de Alicia y no que Juan est en la segunda posicin. Moverse a travs de una lista ligada involucra seguir las ligas desde el principio hasta el final (nodo inicial, nodo final). Adems las listas son marcadas al final apuntando a un valor especial que se llama Nothing (nada). Dado que se trabaja con clases de objetos en memoria, se utiliza el objeto equivalente nulo Nothing, para denotar el final de una lista. Tambin es recomendable marcar el inicio de una lista con un nodo llamado encabezado (Header). La insercin en una lista ligada se vuelve muy eficiente ya que todo lo que implica es cambiar la liga del nodo previo al nodo insertado y establecer la liga del nodo nuevo al punto que el nodo previo apuntaba antes de la insercin.
73
Carolina
La remocin de un nodo es igualmente sencilla ya que implica direccionar la liga del nodo antes de removerlo al nodo que apunta actualmente y establecer la liga del nodo removido a Nothing.
Header
Alicia
Juan
Carolina
Olga
Nothing
Listas Ligadas Orientadas a Objetos. La clase Nodo: Un nodo est compuesto de dos datos miembros. Elemento que almacena el dato del nodo y Liga que almacena la referencia al siguiente nodo. Puesto que se puede usar el tipo de dato Object para el tipo de dato de Elemento no importar que clase de dato sea almacenado en la lista18. Proyecto MDI para Estructuras Lineales: Es la aplicacin (Windows) en donde se analizarn las estructuras lineales Listas, Pilas y Colas. La forma inicial es un contenedor MDI. Nombre MDIELineales, propiedad IsMDIContainer = True con un men como el que se muestra enseguida y un mdulo llamado ModEL.
18
Michael McMillan. DataStructures and Algorithms Using Visual Basic .NET. Cambridge.
74
La clase Lista Ligada: Esta clase incluye algunos mtodos para agregar o remover nodos en la lista, recorrer la lista y encontrar un nodo en particular. Tambin se requiere un constructor que instancie una lista. El nico miembro dato en una lista en la clase es el nodo de encabezado (Header).
Public Class CNodo Public Elemento As Object Public Liga As CNodo Public Sub New() Elemento = Nothing Liga = Nothing End Sub 'Sobrecarga Public Sub New(ByVal ElElemento As Object) Elemento = ElElemento Liga = Nothing End Sub End Class
75
76
77
Objeto inters TextBox Button ListBox Button Button Button Button Button Label
de
Propiedades Name = txtDato Name = btnInserta Name = LaLista Name=btnRemove Name=New Name=btnSave Name=btnOpen Name=btnClose Name=labTL Name=SaveFD, (*.dat)|*.dat DefaultExt=dat Filter=Archivo de datos
Descripcin Captura de datos Insertar el dato en la lista Desplegar la lista actual Quita el elemento seleccionado de la lista. Prepara una lista nueva Guarda la lista actual Abre una lista Cierra la ventana Para mostrar el total de elementos en la lista.
OpenFileDialog
SaveFileDialog
Selecciona almacenada.
una
lista
Public Class frmListaSimple Public oLista As New CListaLigada Public oActual As Object Public Sub New() ' Llamada necesaria para el Diseador de Windows Forms. InitializeComponent() ' Agregue cualquier inicializacin despus de la llamada a InitializeComponent(). Dim sRuta As String = My.Application.Info.DirectoryPath + "\ListaLigadaS" If Not My.Computer.FileSystem.DirectoryExists(sRuta) Then My.Computer.FileSystem.CreateDirectory(sRuta) End If SaveFD.InitialDirectory = sRuta OpenFD.InitialDirectory = sRuta End Sub Private Sub frmListaSimple_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load oActual = oLista.Header End Sub Private Sub btnInserta_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnInserta.Click Dim Item As Object If txtDato.Text.Trim.Length > 0 Then Item = txtDato.Text oLista.Insertar(Item, oActual) oActual = Item VerLista() labTL.Text = LaLista.Items.Count txtDato.Clear() txtDato.Focus() End If End Sub Private Sub VerLista() LaLista.Items.Clear() oLista.VerLista(LaLista) End Sub
78
79
Ejecucin: Las inserciones se hacen en el orden de captura, pero si se hace un clic doble sobre cualquier elemento de la lista ste se vuelve el elemento actual y la siguiente insercin colocar al dato despus de tal elemento. Para eliminar un elemento de la lista, debe seleccionarse (con un clic) en la lista y luego seleccionar .
Se pueden usar cualquier tipo de datos ya que la clase CListaLigada utiliza datos tipo Object.
Caso de evaluacin de competencias adquiridas: Realizar los cambios necesarios a la clase CListaLigada para que: a. Cuente lo elementos en la lista (no debe usarse el control LaLista (ListBox)) de la aplicacin.
80
Pero puede hacerse como se quiera siempre y cuando los cambios en el cdigo se hagan en la clase.
19
Z es un parmetro.
81
Header
Alicia
Juan
Olga
Nothing
Nothin g
Se copia el cdigo de CNodo al la clase recin creada y se hacen las siguientes modificaciones: Public Class CNodoDoble Public Elemento As Object Public LigaS As CNodo 'Liga al siguiente Public LigaA As CNodo 'Liga al anterior Public Sub New() Elemento = Nothing LigaS = Nothing LigaA = Nothing End Sub 'Sobrecarga Public Sub New(ByVal ElElemento As Object) Elemento = ElElemento LigaS = Nothing LigaA = Nothing End Sub End Class
Y la insercin en este tipo de lista es parecida a la que se hace en una lista simple excepto que se tienen que establecer dos apuntadores: Agregar una clase nueva al proyecto:
82
Usando programacin orientada a objetos, este algoritmo puede establecerse de la siguiente manera: Algoritmo Insertar (Nuevo).- Donde Nuevo es el valor que se desea insertar en la lista y sus apuntadores al nodo anterior y al nodo siguiente son LigaA y LigaS respectivamente.
1. Si se va a insertar al final de la lista, entonces: a. b. c. Crear un nodo nuevo y ubicar el ltimo elemento de la lista (U). Crear otro nodo nuevo con la informacin de Nuevo [NodoNuevo(Nuevo)]. Actualizar ligas: NodoNuevo.LigaS U.LigaS NodoNuevo.LigaA U U.LigaS NodoNuevo 2. Insercin despus de un elemento en la lista (Nuevo, DespuesDe).- Donde los parmetros Nuevo y DespuesDe son objetos: a. b. c. d. Crear un nodo nuevo para ubicar al elemento despus del cual se insertar el nodo nuevo (U). Crear otro nodo nuevo con la informacin de Nuevo. (NodoNuevo). Buscar U. Actualizar apuntadores: NodoNuevo.LigaS U.LigaS NodoNuevo.LigaA U NodoNuevo.LigaS.LigaA NodoNuevo U.LigaS NodoNuevo
As, la clase NodoDoble, tendr dos sobrecargas en su constructor: Clase Nodo Doble (agregarla al proyecto):
Public Class CNodoDoble Private mvarElemento As Object Private mvarLigaS As CNodoDoble 'Liga al siguente Private mvarLigaA As CNodoDoble 'Liga al anterior Public Sub New() mvarElemento = Nothing mvarLigaA = Nothing mvarLigaS = Nothing End Sub
20
83
Property LigaS() As CNodoDoble Get Return mvarLigaA End Get Set(ByVal value As CNodoDoble) mvarLigaA = value End Set End Property Property LigaA() As CNodoDoble Get Return mvarLigaS End Get Set(ByVal value As CNodoDoble) mvarLigaS = value End Set End Property
Y la clase para manipular una lista doble sera como sigue: Clase Lista con doble liga (agregarla al proyecto):
Public Class CListaD Protected Header As CNodoDoble Public Sub New() Header = New CNodoDoble("Header") End Sub Private Function Buscar(ByVal Item As Object) As CNodoDoble Dim Actual As New CNodoDoble Actual = Header If Not Actual.LigaS Is Nothing Then Do While (Actual.Elemento <> Item) Actual = Actual.LigaS Loop End If Return Actual End Function Public Function BuscarPrevio(ByVal a As Object) As CNodoDoble Dim Actual As CNodoDoble = Header Dim Prev As CNodoDoble = Header Do While Not (Actual.LigaS Is Nothing) And Actual.Elemento <> a Prev = Actual Actual = Actual.LigaS Loop Return Prev End Function Public Sub Insertar(ByVal Nuevo As Object, ByVal DespuesDe As Object) 'Insercin en medio de la lista: Dim Actual As New CNodoDoble Dim NodoNuevo As New CNodoDoble(Nuevo) 'Ubicar DespuesDe Actual = Buscar(DespuesDe)
84
85
Header
Alicia
Header
Alicia
Juan
21
La propiedad image de los controles es opcional y no necesariamente con las imgenes mostradas, en su
86
Etiquetas labTotal y labTotFiles, mostrarn el total de elementos en la lista doble y el total de archivos (con elementos de una lista) almacenados-
btnSave
btnOpen Tres cuadros de dilogo. btnNew btnClose Las tres listas son controles ListBox. Vista del proyecto:
87
Insercin de datos en secuencia despus de un elemento de la lista, seleccionado con doble clic den ListaA (ListBox). La insercin se realiza al pulsar ENTER en txtDato.
Private Sub txtDato_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtDato.KeyPress If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then If txtDato.Text.Trim.Length > 0 Then Dim Elemento As New Object Elemento = txtDato.Text.Trim If oActual Is Nothing Then ListaD.Insertar(Elemento) Else ListaD.Insertar(Elemento, oActual) oActual = Nothing End If ListaD.VistaListaD(ListaA) ListaD.VistaRev(ListaR) labTotal.Text = ListaD.CuentaItems txtDato.Clear() Else MsgBox("Falta dato", MsgBoxStyle.Information) End If End If End Sub Private Sub ListaA_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListaA.DoubleClick _ , ListaR.DoubleClick Dim Lista As ListBox = sender If Not Lista.SelectedItem Is Nothing Then oActual = Lista.SelectedItem MsgBox("La siguiente insercin ser despus de: " + oActual.ToString) txtDato.Focus() End If End Sub
88
Este procedimiento cambia algunas propiedades de los cuadros de dilogo de acuerdo al tipo de archivo requerido. Ms adelante, los agregados a esta forma como ejercicio, requieren guardar los datos como texto, las listas normales se guardan en archivos de datos (.dat).
Private Sub SetDialogo(ByVal sExt As String) SaveFD.DefaultExt = sExt If sExt = "txt" Then SaveFD.Filter = "Archivos de texto (*.txt)|*.txt" SaveFD.InitialDirectory = RutaPal Else SaveFD.Filter = "Archivos de datos (*.dat)|*.dat" SaveFD.InitialDirectory = sRuta End If SaveFD.FileName = "" OpenFD.InitialDirectory = SaveFD.InitialDirectory OpenFD.DefaultExt = sExt OpenFD.Filter = SaveFD.Filter End Sub Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpen.Click SetDialogo("dat") If Not ListArchivos.SelectedItem Is Nothing Then OpenFD.FileName = ListArchivos.SelectedItem End If OpenFD.InitialDirectory = sRuta If OpenFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim sFile As String = OpenFD.FileName Dim FI As System.IO.FileInfo FI = My.Computer.FileSystem.GetFileInfo(sFile) If FI.Length > 0 Then ListaD = New CListaD ListaD.AbreDatos(sFile, ListaD) ListaD.VistaListaD(ListaA) ListaD.VistaRev(ListaR) labTotal.Text = ListaD.CuentaItems End If End If End Sub Para remover un elemento de la lista: Private Sub btnRem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRem.Click 'Elemento seleccionado en ListaA (a remover) If Not ListaA.SelectedItem Is Nothing Then Dim Borra As Object = ListaA.SelectedItem ListaD.RemoverD(Borra) ListaD.VistaListaD(ListaA) ListaD.VistaRev(ListaR) labTotal.Text = ListaD.CuentaItems End If End Sub
89
As por ejemplo al insertar la siguiente secuencia de datos: Alicia, Juan Carolina, Ricardo, Roxana, las listas hacia adelante y hacia atrs se vern as:
90
Y al pulsar ENTER:
Public Sub ModificaNodo(ByVal Item As Object, ByVal OModifca As Object) Dim Nodo = Buscar(Item) If Not Nodo.Elemento Is Nothing Then Nodo.Elemento = OModifca Else MsgBox(Item + " no existe en la lista", MsgBoxStyle.Information) End If End Sub
91
Ejercicio.- Un palndromo es una frase o palabra que se le igual de izquierda a derecha que de derecha a izquierda. Estos son algunos ejemplos: Somos o no somos Luz azul Anita lava la tina La ruta natural Yo hago yoga hoy. No traces en ese cartn
Modificar la ventana de listas ligadas dobles para determinar si una palabra frase es no un palndromo usando la clase CListaD. Sugerencias: Ampliar el ancho de la forma y agregar un control contenedor Panel con las siguientes propiedades: Name = pnlEj Border Style = Fixed 3D
Dentro del este contenedor, se agregan los elementos que se muestran: Los controles de inters(para el programa) son: txtWord.- TextBox con su propiedad CaracterCasong =
92
Como se observa, es necesario quitar espacios en la frase y escribirla sin acentos, por ejemplo, la frase dbale arroz a la zorra el abad, se escribe sin acentos. Adems sus letras son slo minsculas (el control de texto est configurado as).
sera el siguiente:
Private Sub btnPal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPal.Click Dim Palabra As String = txtWord.Text.Trim If Palabra.Length > 1 Then btnNew.PerformClick() Dim L As Char, i As Short For i = 1 To Palabra.Length L = Mid(Palabra, i, 1) If CStr(L) <> " " Then ListaD.Insertar(L) End If Next With ListaD .VistaListaD(ListaA) .VistaRev(ListaR) End With If EsPalindrome() Then MsgBox("Es un palndrome", MsgBoxStyle.Information) Else MsgBox("No es palndrome", MsgBoxStyle.Information)
93
Aqu, primero se verifica que la palabra sea de longitud mayor 1. Luego se prepara la forma para una lista doble nueva ejecutando programticamente un clic al botn btnNew. El proceso comienza extrayendo cada letra de la palabra o frase ingresada recorrindola letra por letra como se muestra en el ciclo for del procedimiento y usando la funcin Mid de VB.NET. La instruccin:
L = Mid(Palabra, i, 1)
Extrae la letra del objeto Palabra que se encuentra en la posicin i y tomando nicamente 1 carcter. Para insertar nicamente letras sin espacios en blanco en la frase:
If CStr(L) <> " " Then ListaD.Insertar(L) End If
Finalmente se muestran las listas hacia adelante y hacia atrs y se ejecuta el procedimiento
EsPalindrome objeto del ejercicio. Para guardar y abrir frases que demuestren la validez del cdigo escrito, se crea un directorio especial:
Private Sub btnSavePal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSavePal.Click SetDialogo("txt") If SaveFD.ShowDialog = Windows.Forms.DialogResult.OK Then My.Computer.FileSystem.WriteAllText(SaveFD.FileName, txtWord.Text.Trim, False) MsgBox("Frase/Palabra guardada", MsgBoxStyle.Information) End If End Sub Private Sub btnOpenPal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOpenPal.Click SetDialogo("txt") If OpenFD.ShowDialog = Windows.Forms.DialogResult.OK Then Dim sWord As String = My.Computer.FileSystem.ReadAllText(OpenFD.FileName) txtWord.Text = sWord End If End Sub
94
Header
Header
Alicia
Olga
Laura
El modelo usado para la lista ligada simple puede usarse como base para crear una clase para este tipo de listas: En el proyecto actual, agregamos una clase nueva:
Public Class CListaC Protected NodoA As CNodo Protected Header As CNodo Public CuentaNodos As Integer = 0 Public Sub New() Header = New CNodo("Header") Header.Liga = Header End Sub
95
La insercin puede hacerse al principio de la lista o despus de algn otro elemento, por defecto el ltimo.
Public Sub Insertar(ByVal X As Object, ByVal DespuesDe As Object) Dim Actual As New CNodo Dim NodoN As New CNodo(X) Actual = Buscar(DespuesDe) NodoN.Liga = Actual.Liga Actual.Liga = NodoN CuentaNodos += 1 End Sub Public Sub InsertarPrimero(ByVal X As Object) Dim Actual As New CNodo(X) Actual.Liga = Header Header.Liga = Actual CuentaNodos += 1 End Sub
Remocin:
Public Sub Remover(ByVal X As Object) Dim NodoP As CNodo = BuscaPrev(X) If Not NodoP.Liga Is Nothing Then NodoP.Liga = NodoP.Liga.Liga End If CuentaNodos -= 1
96
Uso: Agregar una forma al proyecto actual (frmListaCircular): Los controles de inters en orden descendente son: txtDato (TextBox) chkDespuesDe (CheckBox) LaLista (ListBox) NumNodo (NumericUpDown, Minimum =0,
Maximum = 10) txtArchivo (TextBox) ListaArchivos (ListBox) Los botones son: btnDel btnMove btnSave btnOpen
97
98
Private Sub chkDespuesDe_CheckStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles chkDespuesDe.CheckStateChanged If chkDespuesDe.Checked Then If Not LaLista.SelectedItem Is Nothing Then UDato = LaLista.SelectedItem MsgBox("Siguiente insercin despus de: " + UDato, MsgBoxStyle.Information) txtDato.Focus() Else MsgBox("No se ha seleccionado un elemento en la lista", MsgBoxStyle.Information) chkDespuesDe.CheckState = CheckState.Unchecked End If Else UDato = ListaC.Ultimo.Elemento End If End Sub
Finalmente, para guardar una lista, debe introducirse el nombre del archivo, el cual si existe ser reemplazado con la lista actual.
99
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click If ListaC.CuentaNodos > 0 Then sFile = txtArchivo.Text.Trim If sFile.Length > 0 Then sFile = RutaC + sFile 'Si el archivo existe lo elimina If My.Computer.FileSystem.FileExists(sFile) Then My.Computer.FileSystem.DeleteFile(sFile) End If Dim NA As Short = FreeFile() FileOpen(NA, sFile, OpenMode.Output) For Each D As Object In LaLista.Items PrintLine(NA, D) Next FileClose(NA) VerArchivos() End If End If End Sub
100
Un ejercicio interesante es el siguiente22: De acuerdo a la leyenda, el historiador judo Flavius Josephus fue capturado junto con otros 40 compatriotas por legionarios romanos durante la guerra judeo romana. Los soldados judos decidieron que era preferible suicidarse en lugar de ser capturados (lo que se parece a la saga de Masada) para lo cual disearon un plan para ello. Formaron entonces un crculo para asesinar a cada tercer soldado hasta que todos estuviesen muertos. Jos y otro decidieron que no formaran parte de esto y rpidamente calcularon que era necesario colocarse ellos mismos en el crculo y sobrevivir ambos. Escribir un programa que permita colocar N personas en un crculo y especificar cada M persona debe ser eliminada. El programa debe especificar el nmero de la ltima persona a la izquierda del crculo. Usar una lista ligada circular para resolver el problema. Para resolverlo:
22
101
Puede usarse la ventana actual agregando una seccin para resolver el ejercicio: Panel1
NumM
(NumericUpDown
102
PILAS La Pila es una de las estructuras lineales de tamao variable ms importantes. De forma general, en una lista lineal se pueden realizar inserciones o remociones en cualquier parte esta. Una clase importante de listas permite que la insercin y remocin de un elemento se realice nicamente al final de la lista. Este tipo de clase se conoce como una Pila. A la operacin de insertar un elemento al final de la lista se le conoce como PUSH y a la operacin de eliminar el elemento al final de la lista como POP. El primer y ltimo elemento de una pila debe ser accesible y se conocen como el fondo y el tope de la pila. As la remocin se hace siempre en el orden inverso a como fueron agregados los elementos de una pila.
103
POP
PUSH1 Tope 1
PUSH2 Tope 2 1
Puesto que como generalmente no se conoce el tamao de una pila, lo mejor es usar una estructura dinmica como el ArrayList. La Clase PILA (Agregar al proyecto actual) :
Public Class CPila Private Tope As Integer Private L As New ArrayList Public Sub New() Tope = -1 End Sub ReadOnly Property Count() As Integer Get Return L.Count End Get End Property Public Sub PUSH(ByVal X As Object) L.Add(X) Tope += 1 End Sub Public Function POP() As Object If L.Count > 0 Then Dim x As Object = L.Item(Tope) L.RemoveAt(Tope) Tope -= 1 Return x Else Return Nothing End If End Function Public Sub CLEAR() L.Clear() End Sub Public Function PEEK() As Object 'Regresa el elemento en el tope de la pila If Not Tope = -1 Then Return L.Item(Tope) Else 'Pila vaca Return Nothing End If End Function Public Sub VerPila(ByRef LB As ListBox) LB.Items.Clear() If L.Count > 0 Then L.Reverse() For Each X As Object In L LB.Items.Add(X) Next
104
txtDato (TextBox) btnPush (Button) LaPila (ListBox) btnPop (Button) btnTope (Button) btnCLS (Button) ListaPOP (ListBox) labCount (Label).
105
Tope de la pila:
106
Aplicacin: El problema del Palndromo23 puede resolverse usando una pila y usando esta misma forma:
107
Private Sub btnPal_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPal.Click Pila = New CPila Dim sFrase As String = txtFrase.Text.Trim If sFrase.Length > 0 Then Dim x As Integer, Letra As Char Dim sW1 As String = "" Dim EsPalindromo As Boolean = True For x = 0 To sFrase.Length - 1 Letra = sFrase.Substring(x, 1) If Letra <> " " Then sW1 += Letra Pila.PUSH(Letra) End If Next Pila.VerPila(LaPila) labCount.Text = Pila.Count x = 0 Do While Pila.Count > 0 Letra = Pila.POP ListaPOP.Items.Add(Letra) If Letra <> sW1.Substring(x, 1) Then EsPalindromo = False Exit Do End If x += 1 Loop If EsPalindromo Then MsgBox("Es palndromo", MsgBoxStyle.Information) Else MsgBox("No es palndromo", MsgBoxStyle.Information) End If End If End Sub
La Clase Stack. La clase Stack es una implementacin de la interfaz ICollection que representa a una pila. Esta clase est implementada como un buffer circular que permite obtener espacio dinmicamente para los elementos insertados en la pila. Esta clase forma parte del marco (Framework) .NET. La clase Stack incluye mtodos Push, Pop y Peek. Tiene tambin mtodos para determinar el nmero de elementos en la pila, limpiarla y regresar los valores en la pila como un arreglo. Mtodos Constructores de la clase Stack. Existen tres maneras de instanciar un objeto Stack. El constructor por defecto instancia una pila vaca que inicialmente tiene una capacidad de 10 elementos y puede invocarse como:
Dim Nombres() As String = {"Laura", "Ana", "Juan", "Carolina"} Dim Pila As New Stack(Nombres)
El mtodo POP quitara a Carolina de la pila. El tercer mtodo, permite especificar la capacidad inicial de la pila y se usa si se conoce de antemano cuantos elementos debe contener la pila. Ejemplo:
Ejemplo:
24
109
Comprobacin:
Public Class frmSTACK Private Sub btnConvert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConvert.Click Dim Num As Integer = txtNum.Text Dim Base As Short = NumBase.Value labRes.Text = ToBase(Num, Base) End Sub Private Function ToBase(ByVal n As Integer, ByVal b As Short) As String Dim Digitos As New Stack Dim sR As String = "" Do While n > 0 Digitos.Push(n Mod b) n \= b Loop Do While Digitos.Count > 0 sR += Digitos.Pop.ToString Loop Return sR End Function End Class
110
Se asume que el contenido de la pila para evaluar esta expresin se inicializa con el smbolo # que tiene un valor de precedencia menor que los dems smbolos dados en la tabla. El algoritmo general para esta tarea sera: 1. 2. 3. 4. 5. 6. Inicializar el contenido de la pila con # Extraer el smbolo ms a la izquierda de expresin infija (smbolo de entrada actual). Repetir hasta el paso 6 mientras el smbolo de entrada <># Remover y sacar todos los smbolos en la pila cuya precedencia sea mayor o igual al valor de precedencia del valor del smbolo actual. Colocar en la pila el smbolo actual. Extraer el siguiente smbolo ms a la izquierda en la expresin infija ( smbolo de entrada
actual).
Algoritmo Expresiones si parntesis
25
25
111
112
Implementacin:
Public Class CPolaca Public POLACA As String = "" Private mvarINFIJA As String = "" Private Actual As String = "" Private TEMP As String = "" Private X As Short Public Sub New() X = 0 End Sub Property INFIJA() As String Get Return mvarINFIJA End Get Set(ByVal value As String) mvarINFIJA = value + "#" End Set End Property Private Function RSP(ByVal C As Char) As Short 'Expresin sin parntesis Select Case C Case "+", "-" Return -1 Case "*", "/" Return -1 Case "a" To "z" Return 1 Case "#" Return 0 Case Else Return 0 End Select End Function Private Function FSP(ByVal C As Char) As Short 'Expresin sin parntesis Select Case C Case "+", "-" Return 1 Case "*", "/" Return 2 Case "a" To "z" Return 3 Case "#" Return 0 Case Else Return 0 End Select End Function Private Function SIGUIENTE() As Char If X < mvarINFIJA.Length Then Dim L As Char = mvarINFIJA.Substring(X, 1) X += 1 Return L Else Return vbNullChar End If End Function Public Function POLACASP() As String Dim Pila As New Stack Pila.Push("#") '...........................................[1] Dim Rango As Short = 0 '...................................[2] POLACA = "" INFIJA += "#"
113
Public Class frmPolaca Private Sub btnPolish_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPolish.Click If txtExp.Text.Trim.Length > 0 Then Dim Polaca As New CPolaca Polaca.INFIJA = txtExp.Text.Trim
114
Algoritmo Expresiones con parntesis (y operador de potencia). Tabla 226. Smbolo +, *, a,b,c, ( ) Precedencia de entrada F 1 3 6 7 9 0 Funcin de precedencia en la pila G 2 4 5 8 0 0 Funcinde Rango R -1 -1 -1 1 0 0
Dada una cadena infija de entrada (INFIJA) que representa a una expresin infija la cual termina con ) y cuyos smbolos tienen los valores de precedencia que se muestran en la tabla 2, una PILA y una funcin SIGUIENTE que cuando es invocada regresa el siguiente carcter a ser evaluado, este algoritmo convierte la expresin infija a su polaca equivalente. La variable entera Rango acumula el rango de la expresin. Finalmente TEMP almacena temporalmente el elemento apilado. 1. 2. Inicializar PILA: PILA.PUSH(() Inicializar la cadena de salida y contador de rangos. POLACA
26
Tremblay
115
116
Public Function POLACACP() As String Dim PILA As New Stack INFIJA += ")" PILA.Push("(") POLACA = "" Dim Rango As Short = 0 Actual = SIGUIENTE() Do While Actual <> vbNullChar If PILA.Count = 0 Then POLACACP = "Expresin invlida" Exit Function End If Do While FCP(Actual) < G(PILA.Peek) TEMP = PILA.Pop POLACA += TEMP Rango += RCP(TEMP) If Rango < 1 Then POLACACP = "Expresin invlida" Exit Function End If Loop If FCP(Actual) <> G(PILA.Peek) Then PILA.Push(Actual) Else PILA.Pop() End If Actual = SIGUIENTE() Loop If PILA.Count <> 0 Or Rango <> 1 Then POLACACP = "Expresin no vlida"
'5]
'[6]
'[7] '[8]
117
Cambios en la forma:
Private Sub btnPolish_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPolish.Click If txtExp.Text.Trim.Length > 0 Then Dim Polaca As New CPolaca Polaca.INFIJA = txtExp.Text.Trim If InStr(Polaca.INFIJA, "(") = 0 Then labPolaca.Text = Polaca.POLACASP Else labPolaca.Text = Polaca.POLACACP End If End If End Sub
Ejecucin:
Representa a la expresin algebraica (2) Que al convertirse a su forma polaca queda como: abc*+de/h*(3)
Donde z es el resultado numrico final y las variables a, b, c,, z son valores numricos.
118
Se extraen dos elementos de la pila (c y d) y se ejecuta la operacin <c><operdor><b> R1 b * c (3 * 1 = 3) y este resultado se apila R1 a 3 5
El siguiente smbolo es tambin un operador, luego se extraen dos elemento y se realiza la operacin: R2 a + R1 (5 + 3 = 8) y se apila: R2 e d R2 8 2 4 8 Siguientes smbolos que se extraen:
R1 d e (4 2 = 2) y se apila R1 R2 2 8
Operador * R2 R1 * h (2 * 5 = 10) R2 R1 10 8
119
4.
Ejercicio: Construir una calculadora de expresiones algebraicas infijas que las convierta a su equivalente polaca, y sea capaz de asignar valores numricos a las variables para mostrar el resultado numrico final. Algo como esto:
TxtINIFJA (TextBox, CharacterCasing = Lower) permite ingresar una expresin infija directamente o desde el teclado alfanumrico. Ejemplo:
es una expresin vlida se activa el botn (btnRes, Enabled = False como valor inicial).
Al hacer clic en ste se extraes las variables de la expresin polaca y se muestran en el DataGridView (DGV que se cre con dos columnas: cVar Variable ReadOnly = True, cValue, ReadOnly = False HeaderText= Valor - Numrica entera).
120
Ingreso desde el teclado: El conjunto de botones alfanumricos: Estn nombrados como btn1, btn2, btn3,., btn0. Se usa la propiedad Tag de cada botn para asignar la letra: btn1: Text 1a, Tag = a, bt2: Text 2b, Tag = b, etc.
El conjunto de operadores:
Botones nombrados btnX, btnDiv, btnSum, btnMinus, btnPot, btnPA (, btnPC ) y btnEq (=) Se usa tambin la propiedad Tag para establecer cada operador: btnX, Tag =*, btnDiv, Tag =/, etc, Para ingresar valores desde el teclado de la calculadora se usa un solo evento Clic:
121
Private Sub btnEq_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEq.Click If txtINFIJA.Text.Trim.Length > 0 Then Dim bValida As Boolean = False Dim Polaca As New CPolaca Dim Infija As String = txtINFIJA.Text.Trim Polaca.INFIJA = Infija If InStr(Infija, "(") = 0 Then txtRes.Text = Polaca.POLACASP(bValida) Else txtRes.Text = Polaca.POLACACP(bValida) End If btnRes.Enabled = bValida End If End Sub
En donde se hizo una ligera modificacin a la clase CPolaca con el fin de saber si la expresin fue o no vlida.
Public Function POLACACP(Optional ByVal bValid As Boolean = False) As String Dim PILA As New Stack INFIJA += ")" PILA.Push("(") '[1] POLACA = "" '[2] Dim Rango As Short = 0 '[2] Actual = SIGUIENTE() '[3] Do While Actual <> vbNullChar '[4] If PILA.Count = 0 Then POLACACP = "Expresin invlida" Exit Function End If Do While FCP(Actual) < G(PILA.Peek) '5] TEMP = PILA.Pop POLACA += TEMP Rango += RCP(TEMP) If Rango < 1 Then POLACACP = "Expresin invlida" Exit Function End If Loop If FCP(Actual) <> G(PILA.Peek) Then '[6] PILA.Push(Actual) Else PILA.Pop() End If Actual = SIGUIENTE() '[7] Loop If PILA.Count <> 0 Or Rango <> 1 Then '[8]
122
Exit Function
End If Loop Pila.Push(Actual) '....................................[6] Actual = SIGUIENTE() Loop Do While Pila.Peek <> "#" '................................[7] TEMP = Pila.Pop POLACA += TEMP Rango += RSP(TEMP) Loop If Rango = 1 Then '........................................[8] POLACASP = POLACA bValid = True Else POLACASP = "EXPRESION NO VALIDA" bValid = False Exit Function End If End Function
Para extraer las variables de una expresin polaca vlida usamos una coleccin que est declarada como privada y las muestra en el DGV:
Public Class frmCalc Private Variables As New Collection
Private Sub xVariables(ByVal Infija As String) On Error Resume Next 'Omite valores duplicados Variables.Clear() DGV.Rows.Clear() Dim L As Char, x As Integer For i As Short = 0 To Infija.Length - 1 L = Infija.Substring(i, 1) Select Case L Case "a" To "z" Variables.Add(L, Key:=L) End Select Next
123
Luego deben introducirse directamente los valores numricos de cada variable en la celda correspondiente:
Finalmente: Calcula el resultado final numrico y lo muestra: Escribir este procedimiento de evento siguiendo la metodologa descrita antes para obtenerlo.
Private Sub btnCalc_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalc.Click 'Ejercicio de evaluacin End Sub
Esta solucin no es la nica, puede intentar otra para alcanzar este objetivo usando cualquier otra estructura de datos que considere pertinente. Resultado:
124
Recursin con ayuda de pilas: Los procedimientos recursivos 27 siguiente ejemplo: En la unidad II se mostr el algoritmo recursivo para la funcin Factorial: pueden construirse con ayuda de pilas como lo muestra el
Este mismo procedimiento puede establecerse de la siguiente manera28: FACTORIAL.- Dado un entero N, este algoritmo calcula N!. La pila P se usa para almacenar un registro de activacin asociado con cada llamada recursiva. Cada registro de activacin contiene el valor actual de N y la direccin actual retornada RET_ADDR. TEMP_REC es tambin un registro que contiene dos variables: PARM y ADDRESS. Este registro temporal es necesario para simular la apropiada transferencia de control desde un algoritmo de control del algoritmo FACTORIAL a otro. Siempre que un TEMP_REC es colocado en la pila P, copias de PARM y ADDRESS son apiladas en A y asignadas a N y a RET_ADDR respectivamente. Inicialmente la direccin de retorno se establece a la llamada principal (por ejemplo: (ADDRESS direccin principal). PARM se establece con el valor inicial de N.
27 28
125
1. 2.
Guardar N y regresar direccin: P.PUSH(TEMP_REC) Se alcanz el criterio base? Si N =0 entonces FACTORIAL 1 Ir al paso 4 De otro modo ADDRESS Paso 3 Ir al paso 1
3. 4.
Calcular N! FACTORIAL N * FACTORIAL Restablecer el valor previo de N y regresar direccin: TEMP_REC P.POP (Ejemplo: PARM N, ADDRESS RET_ADDR, P.POP) Ir a ADDRESS
126
4 Estructuras no lineales.
Competencia especifica.- Conocer y aplicar las estructuras no lineales en solucin de problemas del mundo real.
rboles. Definicin.- Un rbol es una estructura de datos no lineal que se usa para almacenar datos de una manera jerrquica. Un rbol es una estructura jerrquica que se aplica sobre una coleccin de de elementos u objetos llamados nodos, uno de los cuales es llamado Raz. Adems se crea una relacin de parentesco entre los nodos dando lugar a trminos como padre, hijo, hermano, sucesor,
ancestro, etc.29
Un rbol es pues un conjunto de nodos conectados por ramas. Un ejemplo de un rbol es el organigrama de organizacin de una empresa.
Raz
Gerente General
Director de Produccin
Direccin de Ventas
Jefe de operaciones
Soporte tcnico
29
127
T C
F E Fig 4.2 H
Sub-rbol
Si un nodo est conectado a otros nodos por debajo de l, se denomina nodo padre y a los nodos por debajo de l se les denomina nodos hijos. Un nodo puede tener cero, uno ms nodos conectados a l. Existe una clase especial de rboles llamados rboles Binarios que restringen el nmero de hijos a no ms de dos. Los rboles binarios tienen ciertas propiedades computacionales que los hacen muy eficientes para muchas operaciones En la figura 2 se puede observar que se pueden visitar ciertos nodos que no estn directamente conectados siguiendo una Ruta de conexiones. Por ejemplo para llegar al nodo R, la ruta sera M T R. El visitar todos los nodos de un rbol se denomina travesa. Un rbol puede dividirse en dos niveles. El nodo raz es el nivel 0, su hijo el nivel 1, sus hijos seran el nivel 3 y as sucesivamente. Un nodo en cualquier nivel se considera la raz de un sub-rbol el cual consiste de esa raz y sus hijos y los hijos de sus hijos. Se define la profundidad de un rbol como nmero de capas en l. Por ltimo, cada nodo en el rbol tiene un valor algunas veces referido como el valor clave. ARBOLES BINARIOS. Un rbol binario se define como un rbol en el cual cada nodo no tiene ms de dos hijos. Los nodos hijos de un nodo padre son referidos como nodo izquierdo y nodo derecho. Para ciertas
128
53
30
80
17
40
75
90
Fig. 4.3 En este rbol los valores menores (a la raz) se almacenan a la izquierda y los mayores a la derecha. Recorridos en un rbol binario. Se llama recorrido del rbol al procedimiento de visitar todos los nodos del mismo de diferentes maneras. Existen tres mtodos de recorridos sobre el rbol: inorder, preorder y postorder. El recorrido inorder visita todos los nodos en orden ascendente de sus valores. Un recorrido en preorder primero visita la raz seguido de los nodos en los sub rboles del hijo izquierdo de la raz. Este procedimiento puede escribirse de manera recursiva. Puesto que el mtodo visita cada nodo de manera ascendente, debe adems visitar tanto el hijo izquierdo como el derecho de cada sub rbol siguiendo con los rboles a la izquierda de la raz antes de continuar con los de la derecha. En el recorrido en preorder la nica diferencia entre ambos son tres lneas de cdigo. La llamada al procedimiento para visualizar un nodo est colocada entre las dos llamadas recursivas del mtodo
inorder.
En el mtodo postorder la diferencia con los dos anteriores es donde se coloca la llamada al
procedimiento para visualizar un nodo y las llamadas recursivas al procedimiento. En el recorrido en postorder, el mtodo primero hace recursin sobre los sub rboles izquierdos y luego sobre los sub rboles derechos. Valores mnimos y mximos en un rbol binario. Para encontrar los valores mximo y mnimo en un rbol binario es casi trivial, en ambos casos debido a las propiedades del mismo. El valor mnimo siempre se encontrar a la izquierda del hijo izquierdo de un sub rbol comenzando con el hijo izquierdo de la raz. Por otro lado, el valor mximo se encuentra en el ltimo nodo a la derecha del sub rbol comenzando con el hijo derecho de la raz.
129
4 0
4 8 4 5 4 9 5 2
5 5 5 8
Fig. 4.4 Otro caso especial es la remocin de un nodo con dos hijos: En el primer caso la solucin es mover el sucesor inorder al lugar del nodo que se elimina (50). Esto funciona bien a menos que el sucesor mismo tenga hijos. Para encontrar al sucesor del nodo original hay que ir al nodo derecho original. Por definicin, este nodo no debera ser mayor que el nodo original. Luego se comienzan a seguir las rutas del hijo izquierdo. Puesto que el valor ms
130
131
132
La forma (frmBTree):
133
Tipo
TextBox. ReadOnly = True CaracterCasing = Upper Button CheckBox ListBox
Descripcin
Permite el ingreso de datos. Acepta el dato. Indica que los datos que se ingresan son nmeros. Muestra los datos del rbol.
lstDatos
txtSalida
TextBox Multiline, ScrollBars = Both, WordWrap = False Button Button Button Button Button
Elimina el nodo seleccionado (en la lista). Limpia el rbol. Guarda la secuencia de datos de entrada. Abre un archivo de datos de entrada. Recorre el rbol en Postorden.
btnPostOrder Button btnInOrder Button btnPreOrder btnClose btnMax btnMin Button Cierra la aplicacin. Recorre el rbol en pre orden. Recorre el rbol en orden.
Button Button SaveFileDialog. DefaultExt = dat, Filter = Archivos de datos (*.dat)|*.dat OpenFileDialog, con las mismas especificaciones que el anterior.
Encuentra el nodo mayor Encuentra el nodo menor Dilogo para guardar archivos.
134
135
Ejecucin:
136
Fig. 4.6.
Dato no numricos:
137
FERNANDE Z
ALVAREZ
LOPEZ
DIAZ
BERNAL
CANALES
Fig. 4.8.
138
Ejercicios: 1. 2. 3. Agregar una funcin a la clase CArbolB que cuente el nmero de ramas en el rbol. Escribir un programa que lea un archivo de texto que almacene en el rbol y despliegue todas las palabras en el archivo y encuentre el nmero de veces que aparecen en el archivo. Una expresin aritmtica como 3 + 4 * 5 / 6 puede ser evaluada usando la correcta precedencia de operadores. Modifique la clase CArbolB para hacer esto.
rboles Balanceados (AVL Trees). Nombrada as (en ingls) por los dos cientficos de la computacin quienes descubrieron esta estructura da datos: G.M. Alelson-Velskii y E.M. Lands en 1962. Los rboles balanceados proporcionan otra solucin para mantener balanceados los rboles binarios. La caracterstica que define a un rbol balanceado es que la diferencia entre la altura de los sub rboles derecho e izquierdo no puede ser nunca mayor que una. Fundamentos de rboles balanceados: Para garantizar que un rbol permanece balanceado, ste compara continuamente las alturas de los sub rboles derecho e izquierdo usando una tcnica llamada rotacin para mantenerlo en balance. Para entender cmo trabaja la rotacin, considrese el ejemplo siguiente:
4 0
3 0
139
4 0 3 0 1
Fig. 4.10.
El sub rbol izquierdo tiene un tamao de 2 pero el derecho lo tiene de cero, violando las reglas de los rboles balanceados. El rbol se balancea realizando una rotacin simple derecha, moviendo 40 abajo a la derecha y el 30 arriba a la derecha resultando:
3 0 1 4 0
140
Fig.
141
poco conectado. Si un grafo tiene una rama entre cada conjunto de vrtices se dice que es un grafo completo.
Sistemas del Mundo Real modelados con Grafos. Los grafos son usados para modelar diferentes tipos de sistemas del mundo real. Un ejemplo es el flujo de trfico. Los vrtices representan intersecciones entre calles y las ramas representan a las calles mismas. Grafos ponderados pueden usarse para representar los lmites de velocidad o el nmero de carriles o callejones. Los modeladores pueden usar el sistema para determinar las mejores rutas y las mejores calles alternas para navegar en trfico denso. Cualquier tipo de sistema de transporte puede modelarse usando un grafo. Por ejemplo, una lnea area puede modelar su sistema de vuelos usando un grafo. Cada aeropuerto en un vrtice y cada vuelo de un vrtice a otro es una rama. Una rama ponderada puede representar el costo de un vuelo desde un aeropuerto a otro, o la distancia entre uno y otro. LA CLASE GRAFO. Representacin de Vrtices: Matriz adyacente. Donde se representan los vrtices visitados (valores booleanos).- Arreglo de dos dimensiones (matriz) donde los elementos indican si existe una rama entre dos vrtices.
142
V0 V0 V1 V2 V3 V4 0 0 1 0 0
V1 0 0 1 0 0
V2 1 1 0 1 1
V3 0 0 1 0 0
V4 0 0 1 0 0
Public Class CVertice Public Visitado As Boolean Public Etiqueta As String Public Sub New(ByVal Texto As String) Etiqueta = Texto Visitado = False End Sub End Class Public Class CGrafo Private Const NUM_V As Integer = 20 Private Vertices() As CVertice Private AdjMatrix(,) As Integer Private NumV As Integer Public Sub New() ReDim Vertices(NUM_V) ReDim AdjMatrix(NUM_V, NUM_V) NumV = 0 Dim i, j As Integer For i = 0 To NUM_V - 1 For j = 0 To NUM_V - 1 AdjMatrix(i, j) = 0 Next Next End Sub Public Sub AddVertex(ByVal Texto As String) Vertices(NumV) = New CVertice(Texto) NumV += 1 End Sub Public Sub AddEdge(ByVal iStart As Integer, ByVal iEnd As Integer) AdjMatrix(iStart, iEnd) = 1 AdjMatrix(iEnd, iStart) = 1 End Sub Public Sub ShoVertex(ByVal v As Integer) Console.Write(Vertices(v).Etiqueta) End Sub End Class
143
Programacin
Lenguaje Ensamblador
144
FP FP OOP ED LE
OOP 1
ED 1
LE
0 1
2 3
FP
OOP
ED
LE
LE
30
145
BUSQUEDA EN PROFUNDIDAD (Depth-First Search)31. Esta bsqueda involucra el segur una ruta desde el vrtice inicial hasta alcanzar el ltimo vrtice, luego se regresa para seguir la siguiente ruta hasta alcanzar el ltimo vrtice y as sucesivamente hasta que no existan rutas que seguir.
Fig. En un alto nivel, la bsqueda en profundidad trabaja as: Primero se marca un punto de inicio el cual puede ser cualquier vrtice. Visitar el vrtice, apilarlo y marcarlo como visitado. Luego ir al siguiente vrtice no visitado, apilarlo y marcarlo. Esto contina hasta alcanzar el ltimo vrtice. Luego se verifica si el vrtice en el tope tiene algunos vrtices adyacentes no visitados. Si no lo hay entonces se vaca la pila y se verifican los siguientes vrtices. Si se encuentra uno, se comienzan a visitar vrtices adyacentes hasta que no existan ms sin ser visitados. Cuando finalmente se alcanza el ltimo vrtice en la pila y no hay ms vrtices adyacentes no visitados se ha completado una bsqueda en profundidad.
Public Class CGrafo Private Const NUM_V As Integer = 25 Private Vertices() As CVertice
31
146
147
Otro ejemplo:
Public Class CGrafo Private Const NUM_V As Integer = 6 Private Vertices() As CVertice Private AdjMatrix(,) As Integer Private NumV As Integer Public Sub New() ReDim Vertices(NUM_V) ReDim AdjMatrix(NUM_V, NUM_V) NumV = 0 Dim i, j As Integer
148
Public Sub DelVertex(ByVal v As Integer) Dim j, R, C As Integer If v <> NumV - 1 Then For j = v To NumV - 1 Vertices(j) = Vertices(j + 1) Next For R = v To NumV - 1 MoveRow(R, NumV) Next 'NumV -= 1 For C = v To NumV - 1 'MoveCol(C, NumV - 1) MoveCol(NumV - 1, C) Next End If End Sub Public Sub TopSort() Dim OV As Integer = NumV Dim gStack As New Stack Dim sTemp As String Do While OV > 0
149
Plan reticular.
150
5 Mtodos de Ordenamiento.
Competencia especifica.- Aplicar el mtodo de ordenamiento pertinente en la solucin de un problema real.
Definicin.- Se denomina ordenamiento (sort) al proceso de ordenar una serie de datos que generalmente estn en un arreglo. Este proceso y la bsqueda (search) de algn dato en particular son probablemente las operaciones ms estudiadas en la Ciencia de la Computacin desde el principio de su era. Muchas de las estructuras que se han desarrollado en este libro fueron diseadas principalmente para ordenar y buscar datos y hacer ms eficiente el almacenamiento de datos en ellas. Aunque los investigadores en esta ciencia han desarrollado varios algoritmos sofisticados para ordenar datos, existen algunos muy simples que el estudiante debe analizar. Estos son: El sort de la burbuja y el sort por seleccin. Para probar estos algoritmos, se propone construir la siguiente aplicacin:
151
152
Crea el arreglo y lo llena aleatoriamente con nmeros en el rango especificado (por defecto 1000 9999. Especifica el rango en que se generarn los nmeros en el arreglo.
Maximum = 20 (Limita a20 el tamao del arreglo de
prueba).
Minimum = 10 (El tamao mnimo del arreglo). chkTest btnCrear DGVA PB txtArreglo Button btnBSort, btnSSel Button btnQSort, btnShell PregressBar TextBox CheckBox Button DataGridView.
Determina el tipo de arreglo a crear (pequeo o grande). Crea un arreglo pequeo y lo muestra en el DataGridView.
AllowUserToAddRows = False, AutosizeColumnsMode = AllCells Visible = False BackColor = White, Multiline = True, ScrollBars = Both, WordWrap = False.
Ordenamiento por Seleccin. Este procedimiento se basa en la manera en se ordenan dato manualmente. Por ejemplo si se tienen las credenciales de los estudiantes de un grupo en principio desordenadas stas pueden ordenarse por apellidos (por ejemplo).
Garca Canales Puente Lpez Acevedo Bernal
Se forma una pila con estas credenciales: Garca Canales Puente Lpez Acevedo Bernal
153
Luego se toma la siguiente (de la pila original), que en este caso es Prez y se acomoda en la segunda pila de manera que queden ordenadas:
Canales
1 49 64 64 64 64
2 53 53 23 23
3 27 27 49 49
4 28 28 28 28
5 70 70 70 70
6 3 3 3 27
7 29 29 29 29
8 69 59 59 59
9 64 64 64 64
En el primer recorrido (i 0) se hacen intercambios para las posiciones (j 1, 3, y 6. Para el siguiente valor de i (i 1), ocurren un slo intercambio en j 2. Para i 2, tambin ocurre un intercambio en j 3.
Siguiente recorrido de i (i 1) 23 64 64 49 49 64 64 28 27 28 64 64 70 70 70 27 27 28 29 29 29 69 69 69 64 64 64 28 70 27 27 29 29 59 69 64 64 49 49 28 70 27 27 29 29 59 59 64 64
En i 3, ocurren intercambios en j 4 y 6. Para i 4 se hace un intercambio en j 5, y en i 5 slo se intercambia para j 6. En i 6 se intercambia para j 7 y 8 y para i 7 en j 8.
28 70 i 2
28 70 i 3
i 4 64 70 28 70 i 5 70
28 64
29 29
59 59
64 64
64 70 70
29 29 64
59 59 59
64 64 64
154
Implementacin:
Imports System.Console Module Module1 Sub Main() BackgroundColor = ConsoleColor.White ForegroundColor = ConsoleColor.Black Clear() Dim Arreglo() As Integer = {64, 49, 53, 27, 28, 70, 3, 29, 59, 64} Dim i, j, Temp, N As Integer N = 9 WriteLine("Arreglo desordenado:") VerArreglo(Arreglo, N) WriteLine("Valores intermedios en el arreglo:") ReadKey() For i = 0 To N - 1 For j = i + 1 To N If Arreglo(j) < Arreglo(i) Then Temp = Arreglo(i) Arreglo(i) = Arreglo(j) Arreglo(j) = Temp End If Next VerArreglo(Arreglo, N) Next WriteLine() WriteLine("Arreglo ordenado:") VerArreglo(Arreglo, N) ReadKey() End Sub Private Sub VerArreglo(ByRef Arr() As Integer, ByRef N As Integer) For i As Integer = 0 To N Write(Arr(i).ToString.PadLeft(2) & " ") Next WriteLine() End Sub End Module
Ejecucin:
155
As con algunas ligeras modificaciones (quitando las relativas a la consola), se pasa este procedimiento al la forma de Windows .
Private Sub btnSSel_Click(ByVal sender Handles btnSSel.Click SortSel() End Sub Private Sub SortSel() Dim i, j, Temp As Integer
As
System.Object,
ByVal
As
System.EventArgs)
For i = 0 To N - 1 For j = i + 1 To N If Arreglo(j) < Arreglo(i) Then Temp = Arreglo(i) Arreglo(i) = Arreglo(j) Arreglo(j) = Temp End If Next Next If chkTest.Checked Then VerEnGrid() VerArreglo() Else VerArreglo() End If End Sub
156
Ordenamiento de la burbuja (Bubble Sort): Este mtodo es una mejora al de seleccin en donde no siempre es necesario hacer N 1 iteraciones ya que cada vez hay un decremento en el recorrido del arreglo y cada vez que termina una iteracin, el elemento mayor queda en su lugar por lo que ya no requiere ser evaluado.
Imports System.Console Module Module1 Sub Main() BackgroundColor = ConsoleColor.White ForegroundColor = ConsoleColor.Black Clear() Dim Arreglo() As Integer = {64, 49, 53, 27, 28, 70, 3, 29, 59, 64} Dim N As Integer N = Arreglo.GetUpperBound(0) WriteLine("Arreglo desordenado:") VerArreglo(Arreglo, N) WriteLine("Valores intermedios en el arreglo:") ReadKey() Bubble(Arreglo, N) WriteLine() WriteLine("Arreglo ordenado:") VerArreglo(Arreglo, N) ReadKey() End Sub Private Sub Bubble(ByRef Arr() As Integer, ByVal N As Integer) Dim U, i, Temp, Cta As Integer
157
Y en la forma:
Private Sub btnBSort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBSort.Click Burbuja() End Sub Private Sub Burbuja() 'Modificado: Dim bSorted As Boolean = False Dim U = N Dim iCta, iTemp As Integer Do While Not bSorted
158
Quick Sort (Ordenamiento rpido). Este mtodo tiene una merecida reputacin de ser el algoritmo ms rpido de los vistos en este captulo lo cual es verdad slo para la mayora de grandes conjuntos de datos desordenados. Si los datos son cuando mucho 100 o menos es recomendable usar cualquiera de los mtodos analizados antes. Para visualizar como opera este algoritmo, imagine que debe ordenar alfabticamente los trabajos de los estudiantes de su grupo. Se selecciona una letra intermedia del alfabeto, por ejemplo M, luego se colocan los trabajos de los estudiantes cuyos apellidos comiencen con las letras A-M en una pila y los apellidos N-Z en otra. Luego se repite el mismo proceso pero haciendo pilas ms pequeas, por ejemplo A-C, D-F, , X-Z que despus son ms fciles de ordenar. Puede verse que este es un proceso recursivo.
159
inferior y superior de la particin que est siendo procesada. La variable K contiene el valor que ha de colocarse en su posicin final dentro de una particin. F es una variable lgica que indica el final del proceso que coloca un registro en su posicin final. Cuando se hace falso, la tabla de entrada ha sido particionada en dos partes desunidas. 1. 2. Inicio. F Verdadero Efectuar ordenamiento: Si LI LS, entonces i LI j LS + 1 K A[LI] Repetir mientras F i i + 1 Repetir mientras A[i] < K (moverse de izquierda a derecha) i i + 1 [Fin Mientras] j j -1 Repetir mientras A[j] > K j j- 1 [Fin Mientras] Si i < j entonces A[i] A[j] (se intercambian registros) De otro modo F Falso [Fin Si] [Fin Mientras] A[LI] A[j] (intercambio de registros) Llamada recursiva QuicSort(LI, j -1) Llamada recursiva QuickSort(j+1, LS) 3. Termina.
Private Sub btnQSort_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnQSort.Click Dim LI As Integer = Arreglo.GetLowerBound(0) Dim LS As Integer = Arreglo.GetUpperBound(0) QSort(LI, LS) VerArreglo() End Sub Private Sub QSort(ByVal LI As Integer, ByVal LS As Integer) Dim F As Boolean, j, i, K As Integer Dim T As Integer = 0 F = True If LI < LS Then
32 33
160
Arreglo desordenado:
161
Ordenamiento por acumulacin (heap sort). Este mtodo hace uso de una estructura de datos llamada heap (acumulacin) que es muy similar a un rbol binario pero con algunas diferencias importantes. A diferencia de los rboles binarios esta estructura es generalmente usa arreglos en lugar de nodos. Existen dos importantes condiciones para crear una acumulacin: 1. 2. Un heap debe estar completo, lo que significa que cada rengln debe estar lleno. Cada nodo contiene datos que son mayores o iguales que los datos en los nodos hijos. Por ejemplo:
10
162
10 00
Para construir este acumulamiento34: 1. 2. 3. 4. 5. 6. 7. Repetir hasta el paso 7 mientras an exista un registro que deba ser colocado en el acumulamiento (heap). Obtener el hijo a colocar en la rama. Obtener la posicin del padre de este hijo. Repetir hasta el paso 6 mientras el hijo tenga un padre y el valor clave del hijo se mayor que su padre. Mover al padre debajo de la posicin del hijo. Obtener la posicin de un padre nuevo para el hijo. Copiar al hijo en su posicin apropiada.
Este es el cdigo:
Private Sub CrearHeap() Dim i, j, Q, K As Integer For Q = 1 To N i = Q K = Arreglo(Q) j = i \ 2 Do While i > 0 And K > Arreglo(j) Swap(i, j) i = j j = i \ 2 If j < 0 Then j = 0 End If Loop
34
Tremblay.
163
El algoritmo Heap Sort es el siguiente: 1. 2. 3. 4. 5. 6. 7. 8. Crear el acumulamiento inicial (CrearHeap). Repetir hasta el paso 8 un total de N 1 veces. Intercambiar el primer registro con el ltimo registro no ordenado. Obtener el ndice del hijo ms grande del nuevo registro. Repetir hasta el paso 8 para los elementos desordenados en al acumulamiento (heap) y mientras el elemento actual sea mayor que el primer elemento. Intercambiar registro y obtener el hijo izquierdo siguiente. Obtener el ndice del siguiente hijo ms grande. Copiar el registro en el lugar apropiado.
Private Sub btnHeap_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHeap.Click HeapSort() End Sub Private Sub HeapSort() Dim i, j, K, Q, T As Integer CrearHeap() For Q = N To 1 Step -1 Swap(0, Q) i = 0 K = Arreglo(i) j = 1 If (j + 1) < Q Then If Arreglo(j + 1) > Arreglo(j) Then j += 1 End If End If Do While j <= (Q - 1) And Arreglo(j) > K Swap(i, j) i = j j = 2 * i If (j + 1) < Q Then If Arreglo(j + 1) > Arreglo(j) Then j += 1 End If ElseIf j > N Then j = N End If Loop Arreglo(i) = K Next VerArreglo() End Sub
Arreglo desordenado:
164
Arreglo grande:
Eficiencia de los diferentes mtodos de ordenamiento: Se agregan los siguientes controles a la forma:
labT1
165
Ejemplo:
Private Sub Burbuja() 'Modificado: Dim Tiempo As New Stopwatch Tiempo.Start() Dim bSorted As Boolean = False Dim U = N Dim iCta, iTemp As Integer Do While Not bSorted iCta = 0 For i As Integer = 0 To U - 1 If Arreglo(i) > Arreglo(i + 1) Then iTemp = Arreglo(i) Arreglo(i) = Arreglo(i + 1) Arreglo(i + 1) = iTemp iCta += 1 End If Next If iCta = 0 Then bSorted = True Else U -= 1 iCta = 0 End If Loop Tiempo.Stop() labT1.Text = Tiempo.Elapsed.Milliseconds VerArreglo() If chkTest.Checked Then VerEnGrid() End If End Sub
As, corriendo los diferentes mtodos para arreglos de tamao 5000 y agregando las instrucciones mostradas arriba en cada uno: Burbuja:
Seleccin:
Quick Sort:
Heap Sort:
35
La velocidad de cada mtodo depende de las capacidades del equipo donde se ejecuta.
166
El ordenamiento por mezcla produce un tercer arreglo C con tamao N + M: C[N + M] que contiene los elementos de A y B ordenados: 1 2 3 4 5 6 7 8 9
167
Imports System.Console Module Module1 Sub Main() BackgroundColor = ConsoleColor.White ForegroundColor = ConsoleColor.Black Clear() Dim A1() As Integer = {1, 3, 5, 7, 9, 11} Dim A2() As Integer = {2, 4, 6, 8, 10} Dim M As Integer = A1.GetUpperBound(0) + A2.GetUpperBound(0) + 1 Dim B(M) As Integer WriteLine("Arreglo 1:") VerArreglo(A1) WriteLine("Arreglo 2:") VerArreglo(A2) MergeSort(A1, A2, B) WriteLine("Mezcla:") VerArreglo(B) ReadKey() End Sub Private Sub MergeSort(ByRef Arr1() As Integer, ByVal Arr2() As Integer, ByVal ArrM() As Integer) Dim i, j, k As Integer Dim N1, N2, M As Integer N1 = Arr1.GetUpperBound(0) N2 = Arr2.GetUpperBound(0) M = ArrM.GetUpperBound(0) i = 0 : j = 0 k = 0 Do While i <= N1 And j <= N2 If Arr1(i) < Arr2(j) Then ArrM(k) = Arr1(i) i += 1 Else ArrM(k) = Arr2(j) j += 1 End If k += 1 Loop If i <= N1 Then
168
Ordenamiento Externo. Son algoritmos que se aplican para ordenar datos que estn almacenados en la memoria secundaria del equipo. Puede usarse cualquiera de los mtodos vistos aqu ya que un archivo puede considerarse como un arreglo en la memoria secundaria. Para mostrar estos procedimientos, se usarn archivos directos que tienen como principal caracterstica que sus registros pueden leerse o escribirse directamente en cualquier rengln.
169
Propiedades Maximun = 5000, Minimum=10, Increment =10 Maximun = 5000, Minimum=10, Increment =10
Uso Establecer el tamao del primer archivo. Establecer el tamao del segundo archivo. Mostrar archivo 1 Mostrar archivo 2 datos del datos del
170
Public Class frmSortExt Private Structure Datos Dim Valor As Integer End Structure Private Archivo1, Archivo2, Ruta As String Private N1, N2, A As Integer Private Sub frmSortExt_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Ruta = My.Application.Info.DirectoryPath + "\Datos" If Not My.Computer.FileSystem.DirectoryExists(Ruta) Then My.Computer.FileSystem.CreateDirectory(Ruta) End If Ruta += "\" ShoFiles() End Sub Private Sub ShoFiles() lstFiles.Items.Clear() For Each sFile As String In My.Computer.FileSystem.GetFiles(Ruta, FileIO.SearchOption.SearchTopLevelOnly, "*.dat") lstFiles.Items.Add(My.Computer.FileSystem.GetName(sFile)) Next End Sub Private Sub btnCrear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCrear.Click Generar() ShoFiles() End Sub Private Sub Generar() Dim LI As Integer = 1 Dim LS As Integer = 100 Dim x, i As Integer
171
172
173
174
La aplicacin funciona de la siguiente manera: 1. 2. Escribir los nombres del par de archivos a generar. Seleccionar
3. 4. 5.
Generar los datos aleatoriamente Mezclar archivos. previo). Cuando se abre un archivo, previamente debe seleccionarse la lista donde ser desplegado. (se pide el nombre del archivo resultante, si existe elimina el
175
Ejercicio: Modifique el mtodo de ordenamiento usado en esta aplicacin y cmbielo por: QuickSort HeapSort
176
6 Mtodos de Bsqueda.
Competencia especifica.- Aplicar el mtodo de bsqueda pertinente en la solucin de un problema real. Competencia especfica: Aplicar el mtodo de bsqueda pertinente en la solucin de un problema real.
Introduccin.- La bsqueda y recuperacin de datos es una tarea fundamental en programacin y es una de las que ms ha sido estudiada. Existen bsicamente dos formas de buscar datos en una lista (o arreglo); la bsqueda secuencial y la
bsqueda binaria. La primera se usa cuando los datos no estn ordenados, la segunda es usada
cuando los datos estn ordenados. Bsqueda Secuencial. Este mtodo es bastante fcil de implementar ya que consiste en recorrer el arreglo hasta encontrar el elemento que se busca: Para ejemplificar lo anterior, se utilizar la misma aplicacin de la Unidad V (Ordenamiento), agregando los siguientes controles en la parte inferior de la forma:
Propiedades
Private Sub btnBSec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBSec.Click If IsNumeric(txtLoc.Text) Then Dim L As Integer = LSup.ToString.Length Dim y As Integer = txtLoc.Text Dim i As Integer, bFound As Boolean = False Dim k, x, z As Integer Dim Tiempo As New Stopwatch Tiempo.Start() For i = 0 To Arreglo.GetUpperBound(0) If Arreglo(i) = y Then bFound = True
177
Private Sub Marcarlo(ByVal P As Integer, ByVal L As Integer, ByVal x As Integer) Dim z, k As Integer Dim d1, d2 As String d1 = x.ToString.PadLeft(L) z = InStr(txtArreglo.Text, d1) d2 = txtArreglo.Text.Substring(z - 1, L + 1) If d1.Trim <> d2.Trim Then Do 'z = InStr(z, txtArreglo.Text, " ") z = InStr(z + 1, txtArreglo.Text, d1) d2 = txtArreglo.Text.Substring(z - 1, L + 1) Loop Until d1.Trim = d2.Trim End If txtArreglo.Focus() txtArreglo.SelectionStart = z - 1 txtArreglo.SelectionLength = x.ToString.PadLeft(L).Length End Sub
Arreglo desordenado:
Buscar x = 3: Bsqueda Binaria. Se aplica nicamente sobre arreglos ordenados. La idea es seguir un procedimiento similar a buscar un telfono especfico en un directorio telefnico. As si se desea buscar el telfono de Prez Alcocer Alicia no se busca pgina por pgina sino que se van abriendo pginas de la A-Z, luego se parte a la mitad esa seccin, resultando por ejemplo M Z, descartando la primera mitad y se repite el proceso, por ejemplo M R hasta llegar a la P. Luego en esos apellidos no leemos
178
10
A estos lmites los representamos por las variables iMin e Max. iMin 0: iMax 9 (N) Luego se divide el arreglo en dos mitades, esta posicin se representa por iMit: Donde iMit TRUNC (iMin + iMax) / 2 Luego: iMit (0+9)/2 = 4 (valor truncado) Si x representa el valor a buscar, entonces se prueba la mitad en que debera estar si existiera: Si x < A[iMit] entonces (debera encontrarse en la primera mitad). Descartar la segunda mitad: iMin iMit + 1 De otro modo, Si x > A[iMit] entonces (debera encontrarse en la segunda mitad). Descartar la primera mitad: iMax iMit 1 De otro modo ( x = A[iMit]), el dato ha sido localizado. Fin Si Y este proceso deber repetirse mientras el dato no sea localizado e iMin <= iMax. As, para activar la bsqueda binaria, agregar la siguiente lnea a todos los mtodos de ordenacin:
Private Sub btnHeap_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHeap.Click HeapSort() btnBBin.Enabled = True End Sub
Private Sub btnBBin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBBin.Click Dim x As Integer = txtLoc.Text BinarySearch(x) End Sub
179
Arreglo ordenado:
Bsqueda por Funciones Hash. Introduccin36. El hash es una tcnica para almacenar y recuperar datos rpidamente. Esta utiliza una estructura de datos llamada tabla hash. An y cuando estas tablas proporcionan mtodos de insercin, remocin y
36
McMillan.
180
Private Function HashSimple(ByVal s As String, ByVal Arr() As String) As Integer Dim T, i As Integer For i = 0 To s.Length - 1 T += Asc(s.Chars(i)) Next Return T Mod Arr.GetUpperBound(0) End Function
181
Para localizar una clave, slo se invoca a la funcin hash y se compara el valor de esa celda con el dato a buscar:
Private Function HashSearch(ByVal s As String, ByVal Arr() As String) As Boolean Dim H As Integer H = HashSimple(s, Arr) If Arr(H) = s Then Return True Else Return False End If End Function
182
El tamao que finalmente sea elegido depende del nmero de registros que se van almacenar en la tabla hash, un nmero seguro parece ser 10, 007 que es primo y los requerimientos de memoria no son lo suficientemente grandes como para afectar el rendimiento del programa:
Dim Nombres(10007) As String, Nombre As String
Con la misma idea de usar el cmputo de los valores ASCII de la clave, el siguiente algoritmo proporciona un mejor hash:
Private Function Hash2(ByVal s As String, ByVal Arr() As String) As Integer Dim i As Integer, T As Long For i = 0 To s.Length - 1 T += 37 * T + Asc(s.Chars(i)) Next T = T Mod Arr.GetUpperBound(0) If T < 0 Then
183
Esta funcin utiliza la regla de Horner37 para calcular la funcin polinomial de 37. Lneas que se modifica:
HashVal = Hash2(Nombre, Nombres) H = Hash2(s, Arr)
Cuando se almacenan ms datos la probabilidad de que ocurran colisiones es alta, para resolver este problema se pueden usar cubos (buckets). Un cubo es una estructura de datos simple almacenada en un elemento de una tabla hash que puede almacenar tems mltiples. En la mayora de las implementaciones esta estructura es a su vez un arreglo pero es mejor usar un arreglo lista (ArrayList), as se evita el problema de requerir ms memoria en caso de ser necesario. Para insertar un tem, primero se usa la funcin para determinar en qu ubicacin del arreglo lista ha de almacenarse, luego se verifica si esa ubicacin ya est ocupada. Si lo est no se hace nada, si no se invoca al mtodo Add del arreglo lista. Para remover un tem, de nuevo se obtiene su valor hash y se revisa el arreglo lista para asegurarse que ese tem existe y liego se elimina.
37
http://www.physics.utah.edu/~detar/lessons/c++/array/node4.html
184
Public Class CBucketHash Private Const Tam As Integer = 101 Private Dato() As ArrayList Public Sub New() Dim i As Integer ReDim Dato(Tam) For i = 0 To Tam - 1 Dato(i) = New ArrayList(4) Next End Sub Private Function Hash(ByVal s As String) As Integer Dim i As Integer, Tot As Long For i = 0 To s.Length - 1 Tot += 37 * Tot + Asc(s.Chars(i)) Next Tot = Tot Mod Dato.GetUpperBound(0) If Tot < 0 Then Tot += Dato.GetUpperBound(0) End If Return CInt(Tot) End Function Public Sub Insertar(ByVal Item As String) Dim H As Integer H = Hash(Item) If Not Dato(H).Contains(Item) Then Dato(H).Add(Item) End If End Sub Public Sub Remover(ByVal Item As String) Dim H As Integer H = Hash(Item) If Dato(H).Contains(Item) Then Dato(H).Remove(Item) End If End Sub Public Sub VerDist(ByVal Arr() As String) Dim i, H As Integer, s As String For i = 0 To Tam - 1 If Dato(i).Count > 0 Then For j As Integer = 1 To Dato(i).Count s = Dato(i).Item(j - 1) Console.WriteLine(i & " " & j & " " & s) Next End If Next End Sub End Class
Cuando en el
se
usan
cubos, lista
el
nmero de elementos usados arreglo debe mantenerse tan bajo como sea posible ya que esto minimiza el trabajo extra que se tiene que hacer cuando se agregan o eliminan hash. lista En tems de la tabla este cdigo, el se
minimiza el tamao del arreglo estableciendo valor inicial a 1 en el constructor. Luego, una vez que se tienen colisiones contina vez. El radio del nmero de la capacidad del cada arreglo lista se hace 2 y as duplicndose
factor
que
de
un
carga.
han mejor
estudios
rendimiento en una tabla hash se logra cuando el factor de carga es 1.0 cuando el tamao de la tabla es exactamente igual al nmero de elementos.
Option Strict On Imports System.Console Module Module1 Private MiHash As New CBucketHash Sub Main() ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim Nombres(99) As String, Nombre As String Dim VariosNombres() As String = {"Ricardo", "Ana", "Teresa", "Susana", "Sandra", "Carolina", "Martha", "Julian", "Yolanda", "Margarita"} Dim i As Integer For i = 0 To VariosNombres.GetUpperBound(0) Nombre = VariosNombres(i) MiHash.Insertar(Nombre) Next MiHash.VerDist(VariosNombres) ReadKey() End Sub End Module
185
Colisiones.
La Clase HashTable (.NET). La clase HashTable es un tipo especial del objeto Dictionary que almacena pares de valores de claves. Dado que esta clase es bastante eficiente, debera ser usada en aplicaciones que requieran tablas hash. Cmo instanciar y agregar datos a un objeto HashTable:
Private MiHash As New CBucketHash Private MiHash As New CBucketHash(71) Private MiHash As New CBucketHash(23, 3.0)
La primera lnea crea una tabla hash con su capacidad y factor de carga por defecto. La segunda lnea crea una tabla hash con capacidad para 71 elementos y un factor de carga por defecto. Y la tercera lnea crea una tabla hash con una capacidad inicial de 23 elementos y un factor de carga de 3.0. Uso:
para que la salida corresponda a cada Sub Main() alumno. ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim Claves() As String = {"Nombre1", "Edad1", "Carrera1"} Dim AA As New ArrayList Dim Alumnos As New Hashtable(17) Alumnos.Add("01Nombre", "Olga Zuiga") Alumnos.Add("02Edad", 19) Alumnos.Add("03Carrera", "ISC") Alumnos.Add("04Gnero", "F") Alumnos.Add("05Nombre", "Sandra Alvarez")
186
Aplicacin: Crear un glosario de palabras reservadas de VB.NET (utilizando la ayuda). Esta aplicacin comienza creando un archivo de texto (usando el bloc de notas y guardando las definiciones en formato UTF-8.
187
Una vez que se cambie el nombre a la forma por defecto, debe guardarse el proyecto en una ubicacin conocida.
Option Strict On Imports System.IO Imports System.Collections Public Class frmGlosario Inherits System.Windows.Forms.Form Private Glosario As New Hashtable
188
Ejecucin:
Ejercicios:
189
190
El tamao del arreglo, incide directamente en el tiempo de ejecucin. Se puede concluir que HeapSort es el ms eficiente en cuanto a lo temporal. Algunos lenguajes (como .NET) contienen libreras sumamente eficientes para resolver una serie de problemas, cual simplifica enormemente la tarea de desarrollar grandes aplicaciones. As por ejemplo, agregando lo siguiente a esa aplicacin:
Private Sub btnSortNet_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSortNet.Click Dim Tiempo As New Stopwatch Tiempo.Start()
38
Unidad V.
191
El cual tarda 0 ms en ejecutarse. Claramente una situacin real es el mejor. La complejidad, por otro lado, no es un nmero es una funcin y sus valores dependen de en qu equipo se ejecuta as los valores obtenidos difieren de acuerdo al equipo. Cada problema tiene uno varios valores que determinan su tamao y se calcula de un tamao genrico y no concreto, as por ejemplo la complejidad de los algoritmos de ordenacin se calcula en base a un arreglo de tamao N y no de 5, 10 5000. Un problema generalmente usado para ejemplificar la complejidad de un algoritmo consiste en encontrar el n-simo trmino de una sucesin de Fibonacci. 1
0
1/3
2
1/5
3
1/8
4
La complejidad en el tiempo depende de cmo se resuelva este problema (por ejemplo una funcin iterativa una recursiva).
Imports System.Console
Module Module1
Module Module1 Sub Main() ForegroundColor = ConsoleColor.Black BackgroundColor = ConsoleColor.White Clear() Dim T As New Stopwatch Dim N As Integer = 37 T.Start() WriteLine("Iterativa_") Dim FBNI As Long = FiboIter(N) WriteLine(T.ElapsedMilliseconds) T.Stop() WriteLine(FBNI) WriteLine() WriteLine("Recursiva") T.Start() Dim FBR As Long = FiboRec(N) T.Stop() WriteLine(FBR) WriteLine(T.ElapsedMilliseconds)
192
El tiempo requerido para completar cada tarea depende del valor N (en este caso 37) que se va a calcular (adems de la potencia del equipo donde se ejecuta).
Otra medida de la complejidad son el nmero de instrucciones necesarias que un algoritmo necesita para completar su tarea:
Claramente, el sort por seleccin es menos complejo en el espacio, y adems debe considerarse que en el HeapSort se invoca al procedimiento CrearHeap.
193
Se observa que entre ms grandes sean los tamaos de los archivos, el proceso de sort externo tarda ms. Una solucin a este problema sera implementar un sort ms rpido (como el heap sort). Aunque el nmero de lneas ser mayor.
Por otro lado, la recuperacin de los datos iniciales desde un archivo existente, es ms rpida que los procesos anteriores porque los datos ya estn ordenados.
39
Ingeniera de Software.
194
Ciertos autores sealan que la complejidad de algoritmos es muy til en el nivel terico pero que no es conveniente obsesionarse demasiado en un nivel prctico. Para cada algoritmo existe un par de medidas generales: El peor de los casos que se denota con la notacin (O micrn Big-O). El mejor de los casos denotado por (omega)
En general es imprescindible conocer el peor de los casos ya que proporciona una visin de lo que puede pasar cuando las cosas van realmente mal. Ejemplo: Para una cierta cantidad de datos n, la desviacin estndar de estos puede medirse por:
Debe modificarse el programa (unas pocas lneas) para medir este tiempo.
195
Con la segunda:
(2)
Este es el cdigo:
196
Este proceso puede mejorarse si, por ejemplo se calcula x2 al momento de ingresar los datos:
197
As, el primer intento con la ecuacin 1 repesentara el peor de los casos, y la ltima modificacin ser el mejor de los casos. Ejercicio: Para el problema de encontrar una ecuacin de ajuste con regresin lineal mltiple41, se tiene el siguiente mtodo42: Ecuacin general de ajuste:
Para J variables independientes (X1, X2, , Xj), la varia dependiente Y. Para la ecuacin anterior utilizando a como una estimacin de y bj como una estimacin de j , las ecuaciones normales son:
..
41 42
198
n X1 A= X2 ... Xj
a b1 Z= b2 . . . bj Yd=
Para simplificar este caso, considrese el caso de tres variables: Y = Consumo anual de carne X1 = Un ndice del precio al por menor de carne X2 = ndice del precio al por menor de la carne de cerdo. Estos son los datos histricos de los ltimos 5 aos (x10)- hipotticos Consumo de carne Y 6 5 4 3 7 Precio de la carne X1 1 1 2 2 4 Precio del cerdo. X2 1 2 1 2 9
Clculos preliminares:
199
Y 6 5 4 3 7 25
X1 1 1 2 2 4 10
X2 1 2 1 2 9 15
YX1 6 5 8 6 28 53
YX2 6 10 4 6 63 89
X1 1 1 4 4
X2 1 4 1 4
X1X2
36 25 16 9 49 135
16 26
81 91
1 2 2 4 36 45
A=
5 10 15
10 26 45
15 45 91
d=
25 53 89
Escribir un programa que lea los valores de muestra (Y, X1, X2) y obtenga los valores de Z siguiendo esta metodologa y luego comprelo con el mostrado en la pgina 58. Cul algoritmo es ms eficiente?
200