Programación y Algoritmia Un enfoque práctico y didáctico para el diseño de algoritmos 5 Algoritmos Puntuales Lic. Oscar Ricardo Bruno, MDU Contenido ALGORITMOS PUNTUALES ___________________________________________ 3 Acciones y funciones para vectores_____________________________________ 3 Acciones y funciones para archivos ___________________________________ 12 Acciones y funciones para pilas_______________________________________ 16 Acciones y funciones para Colas ______________________________________ 17 Acciones y funciones para Listas Ordenadas enlazadas ___________________ 18 Acciones y funciones para arboles ____________________________________ 27 Inserciones en arboles AVL __________________________________________ 32 Funciones recursivas _______________________________________________ 32 Archivos en pascal _________________________________________________ 35 Ejemplo en C con aplicaciones de estructuras enlzadas ___________________ 40 ANEXO 1 Representaciones gráficas de algoritmos_________________________ 42 Diagrama de Nassi-Sneiderman ______________________________________ 42 Diagramas de Jackson ______________________________________________ 42 Diagramas de Lindsay.______________________________________________ 43 Llaves de Warniel __________________________________________________ 44 Notación Algoritmica _______________________________________________ 44 Equivalencias entre notación algorítmica y lenguajes de programación _____ 45 Estilos de Indentación ______________________________________________ 45 BIBLIOGRAFIA _____________________________________________________ 47 ALGORITMOS PUNTUALES Objetivos de aprendizaje Dominando los temas del presente capitulo Usted podrá. 1. Evaluar algoritmos puntuales aplicables a distintas estructuras de datos. 2. Conocer las precondiciones para la utilización de algoritmos puntuales Introducción Se describen a continuación un conjunto de algoritmos puntuales para el manejo de estructuras estáticas y dinámicas. Con una descripción breve de las precondiciones y poscondiciones, utilizando definiciones genéricas para todos los casos Definiciones de tipos Definiciones de los tipos de datos utilizados en los algoritmos que se describen MAX_FIL = 100; Tinfo = TIPO Entero; TinfoC = TIPO <C1 : Td1, C2 : Td2> TVector = TIPO Tabla [1,MAX_FIL] de Tinfo; TPNodo = TIPO Apuntador a Nodo; Nodo = TIPO <Info : Tinfo; sgte : TPNodo> Arbol = TIPO <Info : Tinfo; Izq, Der : TPArbol> Acciones y funciones para vectores BusqSecEnVector(Dato V: Tvector; Dato N: Entero; Dato Clave:Tinfo; Dato_resultado Posic: Entero): una accion Usar este algoritmo si alguna de las otras búsquedas en vectores mas eficientes no son posibles, recordando que búsqueda directa tiene eficiencia 1, búsqueda binaria es logarítmica y búsqueda secuencial es de orden N PRE: V: Vector en el que se debe buscar Clave : Valor Buscado N: Tamaño lógico del vector POS: Posic: Posición donde se encuentra la clave, 0 (Cero) si no esta. LEXICO Controla No superar el tamaño fisico del vector j<= MAX_FIL j : Entero; No leer mas alla del ultimo elemento logico cargado j <= N ALGORITMO Salir si es que encuentra la clave buscada V[j] <> clave Posic = 0; j = 1; //Pone el indice en la primera posición para recorrer el vector// MIENTRAS (j <= MAX_FIL y j <= N y V[j] <> Clave) HACER Inc (j) //Incrementa el indice para avanzar en la estructura// FIN_MIENTRAS; SI (j > N) ENTONCES Posic =0 // No encontró la clave buscada SI_NO Posic = j // Encontró la clave en la posición de índice j FIN_SI; FIN. // Búsqueda secuencial En Vector BusqMaxEnVector(Dato V: Tvector; Dato N: Entero; Dato_resultado Maximo :Tinfo; Dato_resultado Posic: Entero): una acccion PRE: V: Vector en el que se debe buscar (sin orden) N : Tamaño lógico del vector POS: Posic: Posición donde se encuentra el máximo Maximo : Valor máximo del vector. LEXICO j : Entero; Supone que el maximo es el primer valor del vector por lo que le asigna ese valor a maximo y la posición 1 a la posición del maximo. Al haber leido solo un ALGORITMO elemento supone ese como maximo Posic = 1; Maximo = V[1]; PARA j [2, N] HACER Recorre ahora las restantes posiciones del vector, a partir de la SI (v[j] > Maximo) segunda y lcada vez que el valor leido supera al maximo contiene ese valor como maximo y el indice actual como posición ENTONCES del maximo Posic = j; Maximo = v[j]; FIN_SI; FIN_PARA; FIN. // Búsqueda máximo En Vector BusqMinDistCeroEnVector(Dato V: Tvector; Dato N: Entero; Dato_resultado Minimo :Tinfo; Dato_resultado Posic: Entero): una acccion PRE: V: Vector en el que se debe buscar (sin orden) N : Tamaño lógico del vector, existe al menos un valor <> de cero POS: Posic: Posición donde se encuentra el minimo distinto de cero Minimo : Valor minimo distinto de cero del vector. LEXICO Recorre el vector hasta encontrar el primero distinto de cero. i,j : Entero; Al encontrarlo supone ese valor como minimo y el valor del ALGORITMO indice como posición del minimo // J = 1; Mientras (J<=N) Y (V[j] = 0) Hacer Incrementar[j]; Posic = J; Minimo = V[j]; Recorre el vector desde la posición inmediata PARA j [Posic.+1 , N] HACER siguiente hasta la ultima desplazando el minimo SI (v[j]<> 0 Y v[j] < Minimo) solo si el valor es distinto de cero y, ademas, ENTONCES menor que el minimo Posic = j; Minimo = v[j]; FIN_SI; FIN_PARA; FIN. // Búsqueda minimo distinto de cero En Vector BusqMaxySiguienteEnVector(Dato V: Tvector; Dato N: Entero; Dato_resultado Maximo :Tinfo; Dato_resultado Posic: Entero, Dato_resultado Segundo :Tinfo; Dato_resultado PosicSegundo: Entero): una accion PRE: V: Vector en el que se debe buscar N : Tamaño lógico del vector mayor o gual a 2 POS: Posic: Posición donde se encuentra el máximo, PosicSegundo: Posición donde se encuentra el siguiente al máximo Maximo : Valor máximo del vector. Segundo : Valor del siguiente al máximo del vector LEXICO j : Entero; ALGORITMO SI V[1] > V[2] ENTONCES Posic = 1; Maximo = V[1]; Se tiene como precondicion que al menos hay dos valores. Se verifica el valor que esta en la primera PosicSegund = 2; posición y se lo compara con el que esta en la Segundo = V[2]; segunda posición, en el caso de ser mayor, el SINO maximo es ese valor, posición del máximo es uno, el segundo el valor que esta en segundo lugar y Posic = 2; posición del segundo es 2. En caso contrario se Maximo = V[2]; establece como maximo el valor de la segunda PosicSegund =1; posición y segundo el de la primera. Segundo = V[1]; FIN_SI PARA j [3, N] HACER SI (v[j] > Maximo) ENTONCES Segundo = Maximo; PosicSegundo = Posic; Posic = j; Maximo = v[j]; SINO SI Maximo>Segundo ENTONCES Segundo = V[j]; PosicSegundo = j FIN_SI FIN_SI; FIN_PARA; Se verifica luego desde la tercera posición hasta el final. En el caso que el nuevo valor sea mayor que el maximo, se debe contener el anterior maximo en el segundo y al maximo se le asigna el nuevo valor. Cosa similar hay que hacer con las posiciones. Si esto no ocurriera se debe verificar si el nuevo valor supera al segundo, en ese caso debera desplazarlo FIN. // Búsqueda máximo En Vector CargaSinRepetirEnVectorV1(Dato_Resultado V: Tvector; Dato_Resultado N: Entero; Dato Clave:Tinfo; Dato_resultado Posic: Entero; Dato_resultado Enc : Booleano): una accion Utilizar este algoritmo si la cantidad de claves diferentes es fija, se dispone de memoria suficiente como para almacenar el vector y la clave no es posicional(es decir clave e índice no se corresponden directamente con posición única y predecible.Si la posición fuera unica y predecible la busqueda debe ser directa PRE: V: Vector en el que se debe buscar Clave : Valor Buscado N : Tamaño lógico del vector POS: Posic: Posición donde se encuentra la clave, o donde lo inserta si no esta. Retorna 0 (cero) en caso que el vector esta completo y no lo encuentra Enc : Retorna True si estaba y False si lo inserto con esta invocación Carga vector sin orden LEXICO j : Entero; Controla No superar el tamaño fisico del vector j<= MAX_FIL ALGORITMO/ No leer mas alla del ultimo elemento logico cargado j <= N Salir si es que encuentra la clave buscada V[j] <> clave Posic = 0; J = 1; MIENTRAS (j <= MAX_FIL y j <= N y V[j] <> Clave) HACER Inc (j) FIN_MIENTRAS; Si debio superar el tamaño fisico maximo del vector no pudo SI j > MAX_FIL cargarlo y retorna cero como señal de error ENTONCES Si encontro un dato o lo debe cargar esto es en el indice j por lo Posic = 0 que a pos se se asigna ese valor. En el caso que j sea mayor que SI_NO n significa que recorrio los n elemntos cargados del vector, tiene Posic = j: estpacio por lo que debe cargar el nuevo en la posición j. En este caso, y al haber un elemento nuevo debe incrementar n que es el SI (j > N) identificador que controla el tamaño logico del vector ENTONCES Enc =FALSE; // No encontró la clave buscada Inc(N); V[N] = Clave; SI_NO Enc = True // Encontró la clave en la posición de índice j FIN_SI; FIN_SI FIN. // Carga sin repetir en vector BusquedaBinariaEnVectorV1(Dato V: Tvector; Dato N: Entero; Dato Clave:Tinfo; Dato_resultado Posic: Entero; Dato_resultado Pri : Entero): una accion Utilizar este algoritmo si los datos en el vector están ordenados por un campo clave y se busca por ese campo. Debe tenerse en cuenta que si la clave es posicional se deberá utilizar búsqueda directa ya que la diferencia en eficiencia esta dada entre 1, para la búsqueda directa y log2N para la binaria PRE: V: Vector en el que se debe buscar con clave sin repetir Clave : Valor Buscado N : Tamaño lógico del vector POS: Posic: Posición donde se encuentra la clave, o 0 (cero) si no esta Pri : Retorna la posición del limite inferior LEXICO Establece valores para las posiciones de los elementos del vector, Pri contiene el indice del primero, es decir el valor 1, U el indice del ultimo j : Entero; elemento logicio, es decir N. Ademas se coloca en Posic. El valor cero, u,m : Entero; utilizando este valor como bandera para salir del ciclo cuando encuentar ALGORITMO el valor buscado Posic = 0; Pri = 1; U = N; MIENTRAS (Pri < = U y Pos = 0) HACER M = (Pri + U ) div 2 Permanece en el ciclo mientras no encuentre lo buscado, al encontrarlo le asigna a pos el indice donde lo encontro, como es un valor > que cero hace false la expresión logica y sale del ciclo. Si no lo encuentra, y para evirtar ciclo infinito verifica que el primero no tome un valor mayor que el ultimo. Si eso ocurre es que el dato buscado no esta y se debe salir SI V[M] = Clave ENTONCES Posic = M; SI_NO SI Clave > V[M] ENTONCES Pri = M+1 SI_NO U=M–1 FIN_SI FIN_SI FIN_MIENTRAS; FIN. // Búsqueda binaria en vector Si el dato buscado lo encuentra le asigna a posición el indice para salir. Si no lo encuentra verifica si esmayor el dato buscabo a lo que se encuentra revisa en la mitad de los mayores por lo que le asigna al primero el indice siguiente al de la mitad dado que alli no estab y vuelve a dividir el conjunto de datos en la mitas, de ser menor pone como tome ultimo el anterior al de la mitad actual BusquedaBinariaEnVectorV2(Dato V: Tvector; Dato N: Entero; Dato Clave:Tinfo; Dato_resultado Posic: Entero; Dato_resultado Pri : Entero): una acccion PRE: V: Vector en el que se debe buscar clave puede estar repetida Clave : Valor Buscado N : Tamaño lógico del vector POS: Posic: Posición donde se encuentra la primera ocurrencia de la clave. 0 (cero) si no esta. Pri : Retorna la posición del limite inferior LEXICO j : Entero; u,m : Entero; ALGORITMO Posic = 0; Pri = 1; U = N; MIENTRAS (Pri < U ) HACER M = (Pri + U ) div 2 SI V[M] = Clave ENTONCES Posic = M; Pri = M; SI_NO SI Clave > V[M] ENTONCES Pri = M+1 SI_NO U=M–1 FIN_SI FIN_SI FIN_MIENTRAS; FIN. // Búsqueda binaria en vector La busqueda es bastante parecida a lo desarrollado anteriormente, pero en pos debe tener la primera aparicion de la clave buscada que puede repetirse. En la busqueda anterior utilizabamos esta pos como bandera, para saber cuando Sali si lo encontro. En este caso si lo utilizamos con el mismo proposito saldria cuando encuentra un valor oincidente con la clave que no necesariamente es el primero, por lo que esa condicion se elimina. Al encontrarlo en m se le asigna ese valoe a pos, alli seguro esta. No sabemos si mas arriba vuelve a estar por lo que se asigna tambien esa posición al ultimo para seguir iterando y ver si lo vuelve a encontrar. Debe modificarse el operador de relacion que compara primero con ultimo para evitar un ciclo infinito, esto se hace eliminando la relacion por igual. Insisto en el concepto de los valores de retorno de la busqueda binaria. Una particularidad de los datos es que si lo que se busca no esta puede retornal en el primero la posición donde esa clave deberia estar CargaSinRepetirEnVectorV2(Dato_Resultado V: Tvector; Dato_Resultado N: Entero; Dato Clave:Tinfo; Dato_resultado Posic: Entero; Dato_resultado Enc : Booleano): una acccion PRE: V: Vector en el que se debe buscar ordenado por clave Clave : Valor Buscado N : Tamaño lógico del vector La busqueda es bastante parecida a lo desarrollado anteriormente, pero en pos debe tener la primera aparicion de la clave buscada que puede repetirse. En la busqueda anterior utilizabamos esta pos como bandera, para saber cuando Sali si lo encontro. En este caso si lo utilizamos con el mismo proposito saldria cuando encuentra un valor oincidente con la clave que no necesariamente es el primero, por lo que esa condicion se elimina. Al encontrarlo en m se le asigna ese valoe a pos, alli seguro esta. No sabemos si mas arriba vuelve a estar por lo que se asigna tambien esa posición al ultimo para seguir iterando y ver si lo vuelve a encontrar. Debe modificarse el operador de relacion que compara primero con ultimo para evitar un ciclo infinito, esto se hace eliminando la relacion por igual. Insisto en el concepto de los valores de retorno de la busqueda binaria. Una particularidad de los datos es que si lo que se busca no esta puede retornal en el primero la posición donde esa clave deberiaestar POS: Posic: Posición donde se encuentra la clave, o donde lo inserta si no esta. Retorna 0 (cero) en caso que el vector esta completo y no lo encuentra Enc : Retorna True si estaba y False si lo inserto con esta invocación Carga vector Ordenado Al estar el vector ordenadola busqueda puede ser binaria, si lo LEXICO encuentra retorna en posición un valor mayor a cero. Si no lo j : Entero; encuentra el valor de posición sera cero. En este caso, se conoce que en pri es en la posición donde este valor debe estar ALGORITMO Enc = True; BusquedaBinariaEnVectorV(V; N; Clave; Posic; Pri) SI (Posic = 0) ENTONCES Se produce un desplazamiento de los valores Enc = False ; desde el ultimo hasta el valor de pri Posic = Pri; corriendolos un lugar para poder insertar en PARA j [N, Pri](-) HACER la posición pri el nuevo valos. Al pasar por aquí se inserto un nuevo elemento por lo que V[j+1] = V[j]; n, que contiene la cantidad de elementos del FIN_PARA; vector debe incrementarse en uno V[Pri] = Clave; Inc(N); FIN_SI FIN. // Carga sin repetir en vector Versión 2. con vector ordenado OrdenarVectorBurbuja(Dato_Resultado V: Tvector; Dato N: Entero): una acccion Pre: V: Vector en el que se debe ordenar, se supone dato simple N : Tamaño lógico del vector POS: Vector ordenado por clave creciente Usar este algoritmo cuando los datos contenidos en un vector deben ser ordenados. Se podría por ejemplo cargar los datos de un archivo al vector, ordenar el vector recorrerlo y generar la estructura ordenada. Para esto la cantidad de elementos del archivo debe ser conocida y se debe disponer de memoria suficiente como para almacenar los datos. Una alternativa, si la memoria no alcanza para almacenar todos los datos podría ser guardar la clave de ordenamiento y la referencia donde encontrar los datos, por ejemplo, la posición en el archivo. La idea general es ir desarrollando pasos sucesivos en cada uno de los cuales ir dejando el mayor de los elementos en el último lugar. En el primer paso se coloca el mayor en la ultima posición, en el paso siguiente se coloca el que le sigue sobre ese y asi hasta que queden dos elemntos. En ese caso al acomodar el segundo el otro queda acomodado el primer ciclo cuenta los pasos, son uno menos que la cantidad de elementos porque el ultimo paso permite acomodar 2 elementos, por eso el ciclo se hace entre 1 y N – 1 siendo n la cantidad de elementos LEXICO I,J, : Entero; Aux : Tinfo; ALGORITMO PARA i [1, N - 1] HACER PARA j [1, N - i] HACER SI (v[j] > v[j + 1]) ENTONCES Para poder colocar el mayor al final es necesario Aux = v[j]; hacer comparaciones. Se compara el primero con el V[j] = v[j + 1]; segundo y si corresponde se intercambian. Asi hasta V[j + 1] = Aux; llegar al ante ultimo eleemento que se lo compara con el últim. FIN_SI; Al ir recorriendo los distintos pasos, y dado que en FIN_PARA; cada uno se acomoda un nuevo elemento FIN_PARA; corresponde hacer una comparación menos en cada avance, como los pasos los recorremos con i, las FIN comparaciones seran n – i. disminuye en 1 en cada paso OrdenarVectorBurbujaMejorado(Dato_Resultado V: Tvector; Dato N: Entero): una acccion PRE: V: Vector en el que se debe ordenar, se supone dato simple N : Tamaño lógico del vector POS: Vector ordenado por clave creciente LEXICO I,J, : Entero; Aux : Tinfo; Ord : Boolean; ALGORITMO I = 0; REPETIR Inc(i); Ord = TRUE; PARA j [1, N - i] HACER SI (v[j] > v[j + 1]) ENTONCES Ord = False; Aux = v[j]; V[j] = v[j + 1]; V[j + 1] = Aux; FIN_SI; FIN_PARA; HASTA ( Ord o I = N – 1); FIN El algoritmo es similar al anterior, solo que el ciclo de repetición externo no lo hace si es que tiene la certeza, en el paso anterior que los datos ya estan ordenados. Es por eso que agrega una bandera para verificar si ya esta ordenado y cambia el cilo exactp por un ciclo pos condicional. Es decir reemplaza la composición para por la composición repetir hasta OrdenarVectorInserion(Dato_Resultado V: Tvector; Dato N: Entero): una accion PRE: V: Vector en el que se debe ordenar, se supone dato simple N : Tamaño lógico del vector POS: Vector ordenado por clave creciente Este algoritmo consta de los siguientes pasos El primer elemento A[0] se lo considera ordenado; es decir se considera el array con un solo elemento. Se inserta A[1] en la posicion correcta, delante o detras de A[0] segun sea mayor o menor. Por cada iteracion, d i desde i=1 hasta n-1, se explora la sublista desde A[i-1] hasta A[0],buscando la posicion correcta de la insercion ; a la vez se mueve hacia abajouna posicion todos los elementos mayores que el elemento a insertar A[i] para dejar vacia la posicion. Insertar el elemento en l posicion correcta. LEXICO I,J, : Entero; Aux : Tinfo; ALGORITMO PARA I[1..N-1] J = I; Aux = A[i] ; MIENTRAS (J >0 Y AUX < A[J - 1])HACER A[J] = A[J - 1] ; Dec(J) ; FIN MIENTRAS ; A[J] = Aux ; FIN PARA; FIN OrdenarVectorShell(Dato_Resultado V: Tvector; Dato N: Entero): una acccion PRE: V: Vector en el que se debe ordenar, se supone dato simple N : Tamaño lógico del vector POS: Vector ordenado por clave creciente Este algoritmo consta de los siguientes pasos Dividir la lista original en n/2 grupos de dos, considerando un incremento o salto entre los elementos en n/2. Analizar cada grupo por separado comparandolas parejas de elementos, y si no estan ordenados, se intercambian . Se divide ahora la lista en la mitad n/4, con un incremento tambien en n/4 y nuevamente se clasifica cada grupo por separado. Se sigue dividiendo la lista en la mitad de grupos que en el paso anterior y se clasifica cada grupo por separado. El algoritmo termina cuando el tamaño del salto es 1. ALGORITMO Intervalo = n / 2; MIENTRAS Intervalo > 0 HACER PARA I [Intervalo + 1 .. N] HACER MIENTRAS (J > 0) HACER K = J + Intervalo; SI (A[J] <= A[K] ENTONCES J = -1 SINO Intercambio(A[J] ,A[K]) ; J = J – Intervalo ; FINSI ; FIN PARA ; FIN MIENTRAS; FIN. CorteDeControlEnVector(Dato V:Tvector; Dato N: Entero): una acccion Usar este procedimiento solo si se tienen los datos agrupados por una clave común y se requiere procesar emitiendo información por cada subconjunto correspondiente a cada clave. PRE: V: Vector en el que se debe Recorrer con corte de control Debe tener un elemento que se repite y estar agrupado por el. N : Tamaño lógico del vector POS: Recorre agrupando por una clave LEXICO I : Entero; ALGORITMO I = 1; Anterior = TipoInfo; // Inicializar contadores generales MIENTRAS (I<=N) Hacer //inicializar contadores de cada sublote Anterior = V[i] MIENTRAS (I<=N Y Anterior = V[i] HACER // Ejecutar acciones del ciclo I = I+1 // avanza a la siguiente posición FIN_MIENTRAS // Mostrar resultados del sublote FIN_MIENTRAS // Mostrar resultados generales FIN ApareoDeVectores(Dato V1,v2:Tvector; Dato N1,N2: Entero): una acccion Utilizar este procedimiento si se tiene mas de una estructura con un campo clave por el que se los debe procesar intercalado y esas estructuras están ORDENADAS por ese campo común. PRE: V1,V2: Vectores a Recorrer mezclados o intercalados Los vectores deben estar ordenados. N1,N2 : Tamaño lógico de los vectores POS: Muestra la totalidad de los datos con el orden de las estructuras LEXICO I,J : Entero; ALGORITMO I = 1; J = 1; MIENTRAS (I<=N1 o J<=N2) Hacer SI((J > N2) o ((I<=N1) y (V1[I]<V2[J])) HACER ENTONCES Imprimir (V1[I]); I = I + 1; SINO Imprimir(V2[J]); J = J + 1; FIN_SI; FIN_MIENTRAS FIN CargaNMejoresEnVector(Dato_Resultado V: Tvector; Dato_Resultado N: Entero; Dato Clave:Tinfo): una acccion PRE: V: Vector en el que se debe buscar e insertar los mejores Clave: Valor Buscado N: Tamaño lógico del vector POS: Vector con los N mejores sin orden LEXICO j : Entero; Maximo: Tinfo Posic: Entero; ALGORITMO SI (N < MAX-FIL) ENTONCES Inc (N); V[n] = Clave SI_NO BusqMaxEnVector(V; N; Maximo :Tinfo; Posic: Entero); SI (Clave > Maximo) ENTONCES V[Posic] = Clave; FIN_SI; FIN_SI; FIN. // Carga los N mejores en vector Acciones y funciones para archivos Se identifican dos tipos de archivos, archivos de texto y archivos biarios. Los archivos de texto son un conjunto de lineas las cuales tienen 0, 1 o mas caracteres que finalizan con un carácter particular que representa el fin de la linea. Los datos son interpretados como caracteres. <los archivos binario, en cambio, son una secuencia de bytes lmacenados según su representación interna y sin interpretar, en este caso es necesario que sean leidos los datos tal como fueron guardados para poder ser reconocidos como iguales. Operaciones elementales de acceso a archivos: Accion Asignar(a,s) Efecto Asigna al idntificador a la cadena s que representa ub archivo en disco Abrir(a) Prepara el archivo asignado a la variable a para su utilizacion Crear(a) Crea el archivo asignado al identificador a y lo prepra para su acceso Cerrar(a) Cierra el arhivo apuntado por a, actualiza la marca de fin si corresponde LeerCaracter(a,c) Lee el siguiente carácter del flujo apuntado por a y lo almacena en c LeerLinea(a,s) Lee la siguente linea del flujo apuntado por a y la almacena en s GrabarCaracter(a,c) Escribe secuencialmente en el flujo a el caracter c GrabarCadena(a,s) Escribe en el flujo a la cadena s LeerArchivo(a,r) Lee el siguiente tipo de dato (ejemplo registro) del flujo a y lo almacena en r GrabarArchivo(a,r) Graba el siguiente tipo de dato, r, en el flujo a LeerPosicion(a,p,r) Lee del flujo a el valor contenido en l posición p y lo almacena en r GrabarPosicion(a,p,r) Graba en la posicion p del flujo a el valor contenido en r NumeroElementos(a) Retorna el numero de elementos almacenados en el archivo PosicionActual(a) Retorna la posición en la que se encuentra posicionado el puntero actual del archivo. ApuntarA(a,p) Accede a la posición indicada por p en el archivo a. FinArchivo(a) Retorna verdadero si se ha alcanzado la marca de fin de archivo Definiciones de tipos TipoArchivoEntero = TIPO Entero; TipoRegistro = TIPO <Clave : Entero ; Nombre : Cadena>; TipoArchivoRegistro = TIPO Archivo de TipoRegistro; Declaracion de variables ArchTexto : Texto //declra una varible de tipo archivo de texto ArchEntero : TipoArchivoEntero // declara una variable de tipo archivo entero ArchRegistro: TipoArchivoRegistro //declara una variable de tipo archivo registro CrearArchivoEnteros(Dato_Resultado Archivo: TipoArchivoEntero): una Accion Crea un archivo y almacena en el un conjunto de enteros, el proceso termina cuando se ingresa un entero menor o igual a cero. LEXICO I : Entero; ALGORITMO Asignar(Archivo,”Archivo.dat”); Crear(Archivo); Imprimir(‘Ingrese un valor entero’); Leer(i); MIENTRAS (i <> 0) HACER GrabarArchivo(Archivo,i); Imprimir(‘Ingrese un valor entero’); Leer(i); FIN_MIENTRAS Cerrar(Archivo); FIN. RecorrerArchivoEnteros(Dato_Resultado Archivo: TipoArchivoEntero): una Accion Recorre un archivo existente que contiene valores enteros y los muestra por pantalla. LEXICO I : Entero; ALGORITMO Asignar(Archivo,”Archivo.dat”); Abrir(Archivo); MIENTRAS (No Sea FinArchivo(Archivo)) HACER LeerArchivo(Archivo,i); Imprimir(‘El valor almacenado es : ’,i); FIN_MIENTRAS Cerrar(Archivo); FIN. CrearArchivodeRegistros(Dato_Resultado Archivo: TipoArchivoRegistro): una Accion Crea un archivo y almacena en el un conjunto deregistros, el proceso termina cuando se ingresa un entero menor o igual a cero en el campo clave del registro. LEXICO La lectura de cada miembro de un registro R : TipoRegistro; cuando el dispositivo es el teclado debe hacerse ALGORITMO por seprado. Es decir la lectura de un registro por teclado se hace camo a campo Asignar(Archivo,”ArchivoR.dat”); Crear(ArchivoR); Imprimir(‘Ingrese un valor entero’); La escritura de un registro en un archivo (Grabar Leer(R.clave); elarchivo)puede hacersecampo a campo o por la MIENTRAS (R.clave <> 0) HACER etructura completa. Hay lenguajes de Imprmir(‘Ingrese un nombre’); programación omo Pascal que solo permiten esta ultima opcion Leer(R.nombre); GrabarArchivo(Archivo,R); Imprmir(‘Ingrese un valor entero’); Leer(R.Clave); FIN_MIENTRAS Cerrar(Archivo); FIN. RecorrerArchivoRegistros(Dato_Resultado Archivo: TipoArchivoRegistro): una Accion Recorre un archivo exsistente que contiene registros y los muestra por pantalla. LEXICO La lectura de un registro cuando el dispositivo es R : TipoRegistro; un archivo se hace por estructura completa ALGORITMO Asignar(Archivo,”ArchivoR.dat”); Abrir(Archivo); MIENTRAS (No Sea FinArchivo(ArchivoR)) HACER LeerArchivo(Archivo,R); Imprimir los dtos de un registro Imprimir(‘La Clave es : ’,R.clave); cuando el dispositivo es la pantalla se hace miembro a Imprimir(‘El Nombre es : ’,R.nombre); miembro. Es decir por pantalla FIN_MIENTRAS los registros se imprimen campo Cerrar(Archivo); a campo FIN. AgregaArchivodeRegistros(Dato_Resultado Archivo: TipoArchivoRegistro): una Accion Agrega datos a un archivo y almacena en el un conjunto deregistros, el proceso termina cuando se ingresa un entero menor o igual a cero en el campo clave del registro. LEXICO El archivo existe por lo que no hay que crearlo. Para agragar valores debe colocarse el punrtero R : TipoRegistro; en la ultima posición por lo que hay que ALGORITMO desplazarlo tantos registro como el valor Asignar(Archivo,”ArchivoR.dat”); contenidoen cantidad de elementos Abrir(ArchivoR); ApuntarA(Archivo,CantidadElementos(Archivo)) Imprimir(‘Ingrese un valor entero’); Leer(R.clave); MIENTRAS (R.clave <> 0) HACER Imprmir(‘Ingrese un nombre’); Leer(R.nombre); GrabarArchivo(Archivo,R); Imprmir(‘Ingrese un valor entero’); Leer(i); FIN_MIENTRAS Cerrar(Archivo); FIN. AgregaArchivoAlFinalDeOtro(Dato_Resultado Anterior, Actual: TipoArchivoRegistro): una Accion Agrega los datos del archivo actual al final del archivo anterior. LEXICO R : TipoRegistro; Ambos archivos existen por lo que se deben abrir y no crear, para grabar todos los registros del ALGORITMO actual al anterior se debe colocar el puntero del Asignar(Anterior,”ArchivoN.dat”); anterior al final del archivo y recorriendo el Abrir(Anterior); actual se lee y graba en anterior Asignar(Actual,”ArchivoA.dat”); Abrir(Actual); ApuntarA(Anterior,CantidadElementos,Anterior) MIENTRAS (No FinArchivo(Actual)) HACER LeerArchivo(Actual,R); GrabarArchivo(Anterior,R); FIN_MIENTRAS Cerrar(Anterior); Cerrar(Actual); FIN. Acciones y funciones para pilas Pila estructura del tipo LIFO el ultimo en entrar es el primero en salir, en general el uso de esta estructura es adecuado cuando se persigue el propósito de invertir el orden de una estructura dada. Su uso es reservado para los compiladores que los utilizan para recursividad y las notaciones sufijas, por ejemplo. CrearPila(Dato_Resultado Pila: TPNodo): una Accion Las estructuras deben ser creadas, esto es hacer apuntar al valor NULO, o inicializar la estructura antes de comenzar a trabajar con ellas. ALGORITMO Simplemente asigna el valor NULO al puntero Pila = NULO; que controla el inicio de la estructura FIN EsVacia(Dato Puntero: TPNodo) : Boolean una Funcion Esta función determina si hay nodos en la pila, es una forma de verificar la existencia de elementos en la estructura para no producir errores en tiempo de ejecución como por ejemplo intentar sacar cuando ya no hay datos. ALGORITMO EsVaciaPila Puntero = NULO; FIN Retona verdadero si el puntero a punta al valor NULO y falso en caso contrario. La asignación d una expresión logica asigna verdadero al identificador booleano si se cumple la condicion y falso en caso contrario Meter(Dato_Resultado Pila: TPNodo; Dato Valor: Tinfo) una accion Este procedimiento inserta un nuevo nodo en la pila, se encarga de pedir memoria, guardar la información y actualizar los punteros. En esta estructura siempre la pila retorna el valor del primer nodo, y como se agrega adelante, el procedimiento siempre retorna en pila el nodo que acaba de crear. LEXICO Pre Pila Apunta al Inicio o a NULO si esta vacía Pos Pila apunta al primer elemento de la estructura (coincide con el creado La estructura queda perfectamente enlazada. Ptr : TPNodo; ALGORITMO Pide memoria, guarda el valor en el nuevo nodo, hace que el siguiente de este nodo sea pila, es ex Nuevo(Ptr); primero (porque agrega delante del primero) y Ptr^ <Valor, Pila>; pila apunta al nodo creado Pila Ptr FIN. Sacar(Dato_Resultado Pila: TPNodo; Dato_Resultado Valor: Tinfo) una accion Este procedimiento libera el nodo apuntado por pila, se encarga de guardar la información contenida en el primer nodo en valor, por lo que este es un parámetro variable y actualizar los punteros. LEXICO PRE: Pila Apunta al Inicio y no esta vacía POS: Libera el nodo de la cima y retorna en valor la informacion. Pila apunta al nuevo primer elemento de la estructura o a NULO si queda Vacia. La estructura queda perfectamente enlazada. Ptr : TPNodo; ALGORITMO Ptr Pila; Valor Ptr^ .info; Pila Pila^.sgte; Destruir(Ptr); FIN Utiliza un puntero auxiliar para conservar el inicio de la pila, guarda el valor contenido en ese puntero, avanza con la estructura y libera el puntero auxiliar. Acciones y funciones para Colas CrearCola(Dato_Resultado ColaFte,ColaFin: TPNodo): una Accion ALGORITMO ColaFte = NULO; ColaFin = NULO; FIN Agregar(Dato_Resultado Colafte, Colafin: TPNodo; Dato Valor: Tinfo) una accion Este procedimiento inserta un nuevo nodo en la cola, se encarga de pedir memoria, guardar la información y actualizar los punteros. En esta estructura siempre ColaFte retorna el valor del primer nodo, y como se agrega después del último, el procedimiento siempre retorna en colafin el nodo que acaba de crear. LEXICO PRE NULO POS Colafte Apunta al Inicio o a NULO si esta vacía, Cola Fin al final o ColaFte apunta al primer elemento de la estructura. ColaFin apunta al ultimo elemento de la estructura (coincide con el creado) La estructura queda perfectamente enlazada. Ptr : TPNodo; ALGORITMO Se pide memoria se guarda la información y el siguiente del nuevo nodo siempre es el valor Nuevo(Ptr); NULO. Para enlazarlo, como vimos, hay dos Ptr^ <Valor, NULO>; situaciones posibles cuando es el primer nodo, en SI (Colafte = NULO) ese caso el puntero al inicio apunta al nuevo nodo y cuando ya hay por lo menos un nodo, en ese ENTONCES caso se debe enlazar el nuevo nodo a Colafte Ptr continuación del anterior ultimo. En todos los SI_NO casos el puntero al ultimo siempre apuntara al nodo creado. ColaFin^.sgte = Ptr; FIN_SI; ColaFin Ptr FIN. Suprimir(Dato_Resultado Colafte, ColaFin: TPNodo; Dato_Resultado Valor: Tinfo) una accion Este procedimiento libera el nodo apuntado porcolafte, se encarga de guardar la información contenida en el primer nodo en valor, por lo que este es un parámetro variable y actualizar los punteros LEXICO PRE ColaFte Apunta al Inicio y no esta vacia POS Libera el nodo de la cima y retorna en valor la informacion. Colafte apunta al nuevo primer elemento de la estructura o a NULO si queda Vacia, en ese caso, ColaFin tambien apuntara a nulo. La estructura queda perfectamente enlazada. Ptr : TPNodo; Utiliza un puntero auxiliar para conservar el ALGORITMO inicio de lacolaa, guarda el valor contenido en Ptr Colafte; ese puntero, avanza con la estructura y libera el Valor Ptr^ .info; puntero auxiliar Si el puntero al inicio apunta a NULO (cuando saca el ultimo valor), entonces ColaFte ColaFte^.sgte; tambien se hace apuntar al puntero auxiliar al SI (ColaFte = NULO) valor NULO. La unica vez que el puntero al final ENTONCES se modifica, cuando se saca, es en este ultimo caso. ColaFin = NULO FIN_SI; Destruir(Ptr); FIN Acciones y funciones para Listas Ordenadas enlazadas CrearLista(Dato_Resultado Lista: TPNodo): una Accion ALGORITMO Lista = NULO; FIN InsertaNodo(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio o a NULO si esta vacia. Lista apunta al primer elemento de la estructura. No retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. Ptr, PtrNuevo : TPNodo; ALGORITMO SI (lista = NULO o Valor < Lista^.info ENTONCES Nuevo(Ptr); Ptr^ <Valor, Lista>; Lista Ptr SI_NO Si la lista esta vacia, o el valor a guardar es menor que el que esta en la primera posición se coloca delante del primero con un procedimiento identico al de insertar en una pila. Se pide memoria y se guarda la informacion Nuevo(PtrNuevo); PtrNuevo^ <Valor, NULO>; Ptr = Lista; MIENTRAS (PtrNuevo^.sgte <>NULO y Valor > PtrNuevo^.sgte^.info) HACER Pregunta anticipadamente por el valor contenido en el Ptr ptr^.sgte nodo siguiente al apuntado por ptr. Si la informacióna FIN_MIENTRAS ingresar es mayor a la del nodo siguiente debe avanzar una posicion PtrNuevo`.sgte Ptr^.sgte; Ptr^.sgte Ptrnuevo; FIN_SI; FIN. Se enlazan los punteros, como se pregunta por adelantado, el siguiente del nuevo sera el que es siguiente al nodo donde salimos que es el inmediato anterior al nueo valor. El siguiente de ese nodo sea ahora el nuevo. El nuevo lo colocamos entre el que señalamos con ptr y el siguiente InsertaPrimero(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta a NULO porque esta vacia. Lista apunta al primer elemento de la estructura. Ptr: TPNodo; ALGORITMO Nuevo(Ptr); Ptr^ <Valor, NULO>; Lista Ptr FIN. InsertaDelante(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio y noesta vacia. Lista apunta al primer elemento de la estructura. Ptr: TPNodo; ALGORITMO Nuevo(Ptr); Ptr^ <Valor, Lista>; Lista Ptr FIN. InsertaEnMedio(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE Lista Apunta al Inicio no esta vacia. POS Lista apunta al primer elemento de la estructura. No retorna la direccion,queda perfectamente enlazada y ordenada. Ptr, PtrNuevo : TPNodo; ALGORITMO Nuevo(PtrNuevo); PtrNuevo^ <Valor, NULO>; Ptr = Lista; MIENTRAS (PtrNuevo^.sgte <>NULO y Valor > PtrNuevo^.sgte^.info) HACER Ptr ptr^.sgte FIN_MIENTRAS PtrNuevo`.sgte Ptr^.sgte; Ptr^.sgte Ptrnuevo; FIN. InsertaAl Final(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio o a NULO si esta vacia. Lista apunta al primer elemento de la estructura. No retorna la direccion del nodo creado. Ptr, PtrNuevo : TPNodo; ALGORITMO SI (lista = NULO o Valor < Lista^.info ENTONCES Nuevo(Ptr); Ptr^ <Valor, Lista>; Lista Ptr SI_NO Nuevo(PtrNuevo); PtrNuevo^ <Valor, NULO>; Ptr = Lista; MIENTRAS (PtrNuevo^.sgte <>NULO) HACER Ptr ptr^.sgte FIN_MIENTRAS PtrNuevo`.sgte Ptr^.sgte; Ptr^.sgte Ptrnuevo; FIN_SI; FIN. InsertaNodoPorDosCampos(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio o a NULO si esta vacia. Lista apunta al primer elemento de la estructura. Info es un rec¡gistro con al menos dos campos para ordenar No retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. Ptr, PtrNuevo : TPNodo; ALGORITMO SI (lista = NULO) o (Valor.C1 < Lista^.info.C1) o (Valor.C1 =Lista^.info.C1)y(Valor.C2<Lista^.info.c2) ENTONCES Nuevo(Ptr); Ptr^ <Valor, Lista>; Lista Ptr SI_NO Nuevo(PtrNuevo); PtrNuevo^ <Valor, NULO>; Ptr = Lista; MIENTRAS (PtrNuevo^.sgte <>NULO) y ((Valor > PtrNuevo^.sgte^.info) o ((valor.C1 = Lista*.info.C1)y(Valor.C2 >Lista*.info.C2)) HACER Ptr ptr^.sgte FIN_MIENTRAS PtrNuevo`.sgte Ptr^.sgte; Ptr^.sgte Ptrnuevo; FIN_SI; FIN. BuscarNodo(Dato Lista: TPNodo; Dato Valor: Tinfo): TPNodo una funcion LEXICO PRE POS Lista Apunta al Inicio y no esta vacia. Se busca encontrar el nodo que contenga valor como informacion Lista apunta al primer elemento de la estructura. Retorna la direccion del nodo con el valor buscado o NULO esta Ptr : TPNodo; ALGORITMO Ptr = NULO; MIENTRAS (Lista <>NULO Y Ptr = NULO) HACER SI valor = Lista ^.info ENTONCES Ptr = Lista {lo encontro y sale} SINO Lista = Lista ^.sgte {avanza al proximo nodo} FIN_SI FIN_MIENTRAS BuscarNodo = Ptr; FIN. BuscaOInserta(Dato_Resultado Lista,Ptr: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio o a NULO si esta vacia. Lista apunta al primer elemento de la estructura. Retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. No se repite la clave PtrNuevo : TPNodo; ALGORITMO SI (lista = NULO o Valor < Lista^.info ENTONCES Nuevo(Ptr); Ptr^ <Valor, Lista>; Lista Ptr SI_NO Ptr = Lista; MIENTRAS (PtrNuevo^.sgte <>NULO y Valor >= PtrNuevo^.sgte^.info) HACER Similar al procedimiento inserta nodo, pero como no Ptr ptr^.sgte debe insertar siempre se cambia el orden de las FIN_MIENTRAS accines cuando se debe insertar en el medio. En este caso se busca primero y si no esta se crea el nodo y se SI (Ptr^.Info <> Valor) enlazan los punteros. Como ptr en este estado no ENTONCES puede valer NULO y el siguiente si el ciclo de PtrNuevo^.sgte Ptr^.sgte; repetición se hace modificando el operador de relacion por >= en lugar de >. Al salir del ciclo si el valor Ptr^.sgte Ptrnuevo; contenido en el nodo actual es distinto al buscado Ptr PtrNuevo; significa de ese dato no esta en la lista y se debe FIN_SI; inserta, de lo contrario no se inserta. FIN_SI; FIN. InsertaNodo2(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE POS Lista Apunta al Inicio o a NULO si esta vacia. Lista apunta al primer elemento de la estructura. No retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. P,Q,Ptr : TPNodo; ALGORITMO Nuevo(Ptr); Ptr^ <Valor, NULO>; P Lista; Q NULO; MIENTRAS P <> NULO y Valor > p^.info HACER Q P; P P^.sgte; FIN_MIENTRAS; SI (P = Lista) ENTONCES Lista Ptr; SI_NO Q^.sgte Ptr; FIN_SI; Ptr^.sgte P; FIN. SuprimeNodo(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE Lista Apunta al Inicio y no esta vacia POS Libera el nodo si encentra el valor. P, Q : TPNodo; ALGORITMO P Lista; Q NULO: MIENTRAS (P <> NULO y Valor > P^.info) HACER Q P; P P^.sgte: FIN_MIENTRAS; SI (P <> NULO y Valor = P^.info ENTONCES SI Q <> NULO ENTONCES Q^.sgte P^.sgte SI_NO Lista P^.sgte; FIN_SI: Destruir(P): FIN_SI; FIN InsertaNodoListaDoblementeEnlazada(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion // El Nodo tiene un puntero al nodo anterior y un puntero al nodo siguiente LEXICO PRE Lista Apunta al Inicio o a NULO si esta vacia. <Valor,Siguiente,Anterior> POS Lista apunta al primer elemento de la estructura. No retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. Se la puede recorrer en ambas direcciones Ptr, PtrNuevo : TPNodo; ALGORITMO SI (lista = NULO o Valor < Lista^.info ENTONCES Nuevo(Ptr); Ptr^ <Valor, Lista,NULO>; SI lista <> NULO ENTONCES Lista^.anterior Ptr Lista Ptr SI_NO Nuevo(PtrNuevo); PtrNuevo^ <Valor, NULO,NULO>; Ptr Lista; MIENTRAS (Ptr^.sgte <>NULO y Valor > Ptr^.sgte^.info) HACER Ptr ptr^.sgte FIN_MIENTRAS PtrNuevo^.sgte Ptr^.sgte; PtrNuevo^.ant Ptr; Ptr^.sgte Ptrnuevo; SI PtrNuevo^.sgte <> NULO ENTONCES PtrNuevo^.sgte.ant = PtrNuevo; FIN_SI; FIN_SI; FIN. ApareoDeListas(Dato_Resultado ListA,ListB,ListAB) una accion LEXICO PRE ListA y ListB Listas ordenadas simplemente enlazadas. POS ListAB Lista enlazada producto del apareo de las listas dato. Ptr : TPNodo; Puntero auxiliar para insertar como cola VA,VB,VAB: TipoInfo el valor asociado a cada nodo de la lisra ALGORITMO ListAB = NULO; Ptr = NULO; MIENTRAS (ListA <> NULO) O (ListB <> NULO) HACER SI ((ListB = NULO)O((ListA<>NULO)Y(ListA^.info<ListB^.info))) ENTONCES VAB = VA SI_NO VAB = VB FIN_SI Agregar(ListAB,Ptr,VAB); FIN_MIENTRAS; Ptr = NULO; FIN. ListaParalelaParaAgrupar(Dato_Resultado ListA, Dato ArchDatos,ArchProceso : TipoArchivo) una accion LEXICO PRE ListA Lista Paralela al archivo de datos, con tantos nodos como registros tiene ese archivo. Las restricciones del nodo no alcanzan para poner la clave de ordenamiento y solo se puede poner un campo que agrupe datos del archivo de proceso. ArchDatos es el archivo de datos personales, contiene todas las claves, esta ordenada por esa por lo que es posible hacer búsqueda binaria. ArchProceso es el archivo a procesar contiene la clave por la que se vincula con el archivo de datos con lo que esta ordenado. Se busca hacer una lista paralela para agrupar evitando busquedas secuenciales en archivos. POS ListA contendra el valor acumulado de cada clave del archivo de datos relacionados posicionalmente. ALGORITMO ListA = NULO; PARA I [1 .. CantidadRegistros(ArchDatos)] HACER InsertaDelante(ListA, 0); //Crea la lista con los contadores en cero// FIN_PARA MIENTRAS (HayaDatos(ArchProceso)) HACER LeerRegistro(ArchProceso, Registro); BusquedaBinaria(ArchDatos, Registro.Clave; Pos); Ptr = Lista; Para J [1 .. Pos] HACER Ptr = Ptr*.sgte; FIN_PARA Incrementar(Ptr*.info, Registro.Agregado); FIN_MIENTRAS; FIN. ListaParalelaParaBuscar(Dato_Resultado ListA, Dato ArchDatos,ArchProceso : TipoArchivo) una accion LEXICO PRE ListA Lista Paralela al archivo de datos, con tantos nodos como registros tiene ese archivo. Las restricciones del nodo no alcanzan para poner la posición en el archivoclave de ordenamiento y solo se puede poner un campo que agrupe datos del archivo de proceso. ArchDatos es el archivo de datos personales, contiene todas las claves, No esta ordenado lo que no es posible hacer busqueda directa ni búsqueda binaria.Se lo carga en una lista como cola para poder buscar en la lista y luego accedre al archivo según el numero de nodo ArchProceso es el archivo a procesar contiene la clave por la que se vincula con el archivo y hay que ir a buscar un valor. Se busca hacer una lista paralela, cargada como cola para buscar evitando busquedas secuenciales en archivos. POS ListA contendra el la clave de busqueda y para cada clave del archivo de datos se relacionan posicionalmente según el numero de nodo. ALGORITMO ListA = NULO; Aux = NULO PARA I [1 .. CantidadRegistros(ArchDatos)] HACER Leer(Registro(ArchDatos, Registro) Agregar(ListA, Aux, Registro.clave); //Crea la lista con la clave a buscar// FIN_PARA Aux = NULO // Para que el resultado sea una lista y no una cola MIENTRAS (HayaDatos(ArchProceso)) HACER LeerRegistro(ArchProceso, Registro); Ptr = Lista; NumeroNodo = 0; MIENTRAS Ptr*.info <> Registro.clave HACER Ptr = Ptr*.sgte; Incrementar(NumeroNodo); FIN_MIENTRAS AccesoDirectoArchivo(ArchDatos, NumeroNodo); LeerRegistro(ArchDatos, RegistroDatos); Imprimir(Registrodatos.Otra clave); FIN_MIENTRAS; FIN. InsertaNodoListaCircular(Dato_Resultado Lista: TPNodo; Dato Valor: Tinfo) una accion //El Puntero a una lista circular apunta al predecesor al primer elemento LEXICO PRE Lista Apunta al al predecesor al primer elemento. Lista no vacia, al menos un nodo Si hay un solo nodo apunta a si mismo POS Lista apunta al primer elemento de la estructura. No retorna la direccion del nodo creado, salvo si es el primero La estructura queda perfectamente enlazada y ordenada creciente. Ptr, Auxiliar : TPNodo; Salir Booleano; ALGORITMO Nuevo(Auxiliar); Aux^ <Valor, NULO>; Lista Ptr SI (lista = NULO) ENTONCES Auxiliar^.sgte = Auxiliar; Lista = Auxiliar; SI_NO {La lista no esta vacia} Ptr = Lista; Salir = FALSO REPETIR SI (Ptr^.sgte^.info< Valor) ENTONCES Ptr ptr^.sgte SINO Salir = Verdadero FIN_SI HASTA Salir o Ptr = Lista Auxiliar^.sgte Ptr^.sgte; Ptr^.sgte Auxiliar; SI (Salir = FALSO) ENTONCES Lista = Auxiliar FIN_SI; {de la lista no vacia} FIN. Acciones y funciones para arboles RecorrerEnOrdenArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa en orden. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerEnOrdenArbol(Arbol^.izquierdo); Imprimir(Arbol*.info); RecorrerEnOrdenArbol(Arbol^.Derecho); FIN_SI; FIN. RecorrerPreOrdenArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa en pre orden. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerPreOrdenArbol(Arbol^.izquierdo); Imprimir(Arbol*.info); RecorrerPreOrdenArbol(Arbol^.Derecho); FIN_SI; FIN. RecorrerPosOrdenArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO Pre Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa pos orden. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerPosOrdenArbol(Arbol^.izquierdo); Imprimir(Arbol*.info); RecorrerPosOrdenArbol(Arbol^.Derecho); FIN_SI; FIN. RecorrerEnOrdenInArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa en orden inverso. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerEnOrdenInArbol(Arbol^.derecho); Imprimir(Arbol*.info); RecorrerEnOrdenArbol(Arbol^.Izquierdo); FIN_SI; FIN. RecorrerPreOrdenInArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa en pre orden inverso. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerPreOrdenInArbol(Arbol^.Derecho); Imprimir(Arbol*.info); RecorrerPreOrdenArbol(Arbol^.Izquierdo; FIN_SI; FIN. RecorrerPosOrdenInArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz o es Nulo. POS Recorre la estructura completa pos orden inverso. ALGORITMO SI (Arbol <> NULO) ENTONCES RecorrerPosOrdenArbol(Arbol^.derecho); Imprimir(Arbol*.info); RecorrerPosOrdenArbol(Arbol^.izquierdo; FIN_SI; FIN. RecorrerEnAnchoPrimero(Dato Arbol: TPNodo; Dato Valor: Tinfo) una accion //El Nodo tiene puntero al hijo izquierdo Y derecho LEXICO PRE Arbol Apunta al nodo raiz no es Nulo. POS Recorre la estructura completa ancho primero. Fte, Fin: TPNodo // Saca el nodo del árbol y lo va cargando en una cola, un nodo hay. Luego recorre hasta que la cola quede vacía. Por cada nodo que va recorriendo, y como solo puede tener dos hijos por ser binario, si hay nodo izquierdo lo agrega en la cola, si hay derecho también lo agrega (esto asegura el recorrido en ancho primero). Al colocar el nodo completo del árbol en la cola, cuando se saca se tienen los enlaces a los hijos, si es que tiene.// ALGORITMO Fte = NULO; Fin = NULO; Agregar(Fte, Fin, Arbol); Mientras (Fte <> NULO) HACER Suprimir(Fte, Fin, Arbol); Imprimir(Arbol*.info); SI (Arbol*.izq<>NULO ENTONCES Agregar(Fte, Fin, Arbol*.izq) FIN_SI SI (Arbol*.der<>NULO ENTONCES Agregar(Fte, Fin, Arbol*.der) FIN_SI; FIN_MIENTRAS; FIN. InsertarNodoArbol(Dato_Resultado Arbol: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE Arbol Apunta al nodo raiz o es Nulo.<izquierdo, info, derecho> Las Inserciones se hacen siempre en las hojas POS Inserta un nodo ordenado ALGORITMO SI (Arbol <> NULO) ENTONCES Nuevo(Arbol); Arbol^ <NULO, Valor, NULO>; SINO SI (Valor<Arbol^.info) ENTONCES InsertarNodoArbol(Arbol^.izquierdo, Valor) SINO SI (Valor>Arbol^.info) ENTONCES InsertarNodoArbol(Arbol^.izquierdo, Valor) SINO ERROR FIN_SI FIN_SI FIN_SI; FIN. CantidadHojasArbol(Dato Arbol: TPNodo): Entero una funcion; Eshoja(Dato Arbol): Booleano una funcion; ALGORITMO EsHoja (Arbol^.izquierdo = NULO) Y (Arbol^.derecho = NULO; FIN /*EsHoja ALGORITMO SI (Arbol <> NULO) ENTONCES SI (EsHoja(Arbol)) ENTONCES CantidadHojas = 1; SINO CanidadHojas CantidadHojas(Arbol^.izquierdo) + CantidadHojas(Arbol^.derecho); SINO CantidadHojas = 0; FIN_SI; FIN. AlturaArbol(Dato Arbol: TPNodo): Entero una funcion; Maximo(Dato A, B : Entero): Entero una funcion; ALGORITMO SI (A > B) ENTONCES Maximo = A; SINO Maximo = B; FIN_SI FIN /*Maximo ALGORITMO SI (Arbol <> NULO) ENTONCES AlturaArbol 1 Maximo(AlturaArbol(Arbol^.izquierdo),AlturaArbol(Arbol^.derecho)) SINO AlturaArbol -1 FIN_SI; FIN. BuscarEnArbol(Dato Arbol: TPNodo; Dato Valor: Tinfo): Booleano una funcion LEXICO PRE Arbol Apunta al nodo raiz o es Nulo.<izquierdo, info, derecho> Busca el dato contenido en Valor POS Retorna Verdadero si lo encuentra o falso en caso contrario. ALGORITMO SI (Arbol <> NULO) ENTONCES Si (Valor< Arbol^.info) ENTONCES BuscarEnArbol BuscarEnArbol(Arbol^.izquierda, valor) SINO SI (Valor>Arbol^.info) ENTONCES + BuscarEnArbol BuscarEnArbol(Arbol^.derecho, valor) SINO BuscarEnArbol VERDADERO FIN_SI FIN_SI SINO BuscarEnArbol FALSO; FIN_SI; FIN. Borrar(Dato_Resultado Arbol: TPNodo; Dato Valor: Tinfo) una accion LEXICO PRE Arbol Apunta al nodo raiz o es Nulo.<izquierdo, info, derecho> POS Busca el dato contenido en Valor y si lo encuentra libera el nodo BorrarInOrder(Dato_Resultado Arbol) ALGORITMO SI (Arbol^.derecho<> NULO ENTONCES BorrarInOrder(Arbol^.derecho) SINO Auxiliar^.info Arbol^.info; Auxiliar Arbol; Arbol Arbol^.izquierdo; FIN_SI FIN ALGORITMO SI (Arbol <> NULO) ENTONCES Si (Valor< Arbol^.info) ENTONCES Borrar(Arbol^.izquierda, Valor) SINO SI (Valor>Arbol^.info) ENTONCES Borrar(Arbol^.derecho, valor) SINO /* en este estado lo encontro*/ Auxiliar = Arbol; SI (Arbol^.derecha = NULO)/* No tiene hijo derecho ENTONCES Arbol = Arbol^.Izquierda SINO SI(Arbol^.izquierda = NULO) ENTONCES Arbol = Arbol^.derecha SINO BorrarInOrder(Arbol^.izquierdo) FIN_SI FIN_SI Liberar(Auxiliar); FIN_SI FIN_SI SINO ERROR; FIN_SI; FIN. Inserciones en arboles AVL Insercion en el sularbol izquierdo de la rama izquierda de A Rotacion Simple Izquierda Izquierda N1^.izquierdo N1^.derecho (N es el nodo desbalanceado N1 su hijo izquierdo) N1^.derecho N1 N N1 Insercion en el sularbol derecho de la rama izquierda de A Rotacion Doble derecha Izquierda N1^. izquierdo N2^. derecho N2^. derecho N1 N^. derecho N2^. izquierdo N2^.izquierdo N N N2 Insercion en el sularbol derecho de la rama derecha de A Rotacion Simple Derecha Derecha N1^.derecho N1^. izquierdo (N es el nodo desbalanceado N1 su hijo derecho) N1^.izquierdo N1 N N1 Insercion en el sularbol izquierdo de la rama derecha de A Rotacion Doble Izquierda derecha N1^. derecho N2^. izquierdo N2^. izquierdo N1 N^.izquierdo N2^.derecho N2^.derecho N N N2 Funciones recursivas El flujo de control de una función recursiva requiere tres condiciones para una terminación normal: 1. Un test para detener o continuar con la recursion. 2. Una llamada recursiva para continuar la recursion 3. Un caso base para terminar la recursion Recursividad SI (Es el caso base) ENTONCES Ejecutar la accion final Terminr recursion SINO Ejecutar accion para cercar a la solucion Invocar nuevamente a la funcion Factorial (Dato N : Entero): Entero una funcion; ALGORITMO SI (N = 0) ENTONCES Factorial = 1 SINO Factorial = N * Factorial(N-1) FINSI FIN. Fibonacci (Dato N : Entero): Entero una funcion; ALGORITMO SI (N = 0) O (N = 1) ENTONCES Fibonacci = N SINO Fibonacci = Fibonaci(N-2)+Fibonacci(N-1) FINSI FIN. EuclidesMaxCD (Dato M,N : Entero): Entero una funcion; ALGORITMO SI (N <= M) Y (M Modulo N = 0) ENTONCES EuclidesMaxCD = N SINO SI (M<N) ENTONCES EuclidesMaxCD(N,M) SINO EuclidesMaxCD(N, M Mod N) FINSI FIN. Hanoi (Dato Inicio, Medio, Centro : Cráter: N : Entero): NULO una funcion; ALGORITMO SI (N = 1) ENTONCES Imprimir(Mover Disco N de inicial a final) SINO Hanoi(Inicial, Final, Central, N- 1); Imprimir(Mover Disco N de inicial a final) Hanoi(Central, Final, Inicial, N- 1); FINSI FIN. Recursividad indirecta Funcion mutuamente reursiva implementdas en C Imprimir los carcteres del alfabeto ingles # incluye <stdio.h> void FuncionA(char c); void FuncionB(char c); int main() { FuncionA(‘Z’); Return 0; } void FuncionA(char c) { if( c > ‘A’ ) FuncionB(c); Printf(“%c”,c); } void FuncionB(char c) { FuncionA(--c); } Determinar si un numero es par # incluye <stdio.h> void FuncionPar(int n); void FuncionImpar(int n); int main() { if (FuncionPr(9)) printf(“Es par”); else printf(“Es Impar”); return 0; } int FuncionPar(int n) { if (n == 0) return 1; else return FuncionImpar(n-1); } int FuncionImpar(int n) { if (n == 0) return 0; else return FuncionPar(n-1); } Archivos en pascal Pascal Dispone del tipo de dato text que permite vincular a una variable interna con un archivo de texto. En el caso de C los nombres internos se declaran como un puntero a una struct FILE, y la discriminacion del tipo, texto o binario se realiza en la apertura Para trabajar con archivos de texto en Pascal se debe: 1. Declarar el nombre lógico del archivo con un identificador de tipo text. 2. Relacionar el nombre interno o lógico con l externo o físico, mediante Assign. 3. Abrirlo con Reset o Rewrite según corresponda. En el ejemplo que sigue se desarrollan las acciones para lectura completa de un archivo de texto. Se lee 1. Carácter a carácter. 2. Por línea completa. 3. Con formato a. En datos simples b. En registros program LeerCaracteres; {Lee un archivo de texto caracter a caracter y lo muestra por pantalla} Arch : text; Letra : char; begin Assign (Arch,'C:\....\archivo.txt'); Reset(Arch); while not EOF(Arch) do begin {Lectura caracter a caracter} read(Arch, Letra); write(Letra); end; Close(Arch); End. program LeerPorLineas; Arch : text; Nombre : string; begin Assign (Arch,'C:\...\archivo.txt'); Reset(Arch); while not EOF(Arch) do begin {Lectura por linea} readln(Arch, nombre); writeln(nombre); end; Close(Arch); End. program LeerConFormato; var Arch : text; Entero : Integer; Texto : string[10]; begin Assign (Arch,'C:\...\archivo.txt'); Reset(Arch); while not EOF(Arch) do begin {Lectura con formato} readln(Arch, Entero, Texto); writeln('Este es el entero : ', Entero:8); writeln('Este es el texto : ', Texto:8); end; Close(Arch); End. program LeerConFormatoEnRegistro; TipoRegistro = Record Numero : Integer; Cadena : string[10]; End; var Arch : text; Registro : TipoRegistro; begin Assign (Arch,'C:\...\archivo.txt'); Reset(Arch); while not EOF(Arch) do begin {Lectura con formato en regitro} readln(Arch, Registro.Numero, Registro.Cadena); writeln('El entero del reg.: ', Registro.Numero:8); writeln('El texto del re. : ', Registro.Cadena:8); end; Close(Arch); End. Los archivos de tipo o de acceso directo es una colección de datos del mismo tipo con almacenamiento sin interpretar y guardadas según su representación interna. Solo se pueden comparar como iguales si son leídos del modo en que fueron escritos Requieren en pascal que para poder utilizarlos se deba hacer y en orden los siguientes pasos 1. 2. 3. El la cláusula Type definir los tipos a. Para el registro si corresponde, o podria evitarse se se utilizan archivo de de tipos de datos primitivos b. Para el archivo NombreDelTipo = FILE OF TIPO DE DATO Declarar las variables en la clausula Var a. Una para el archivo b. Otra para el tipo de dato de cada posición. Asignar y abrir los archivos a. La asignación a traves de ASSIGN vinculando el nombre interno con el externo. b. La apertura según corresponda con Reset o Rewrite Lo disponible para archivos, una vez en condiciones de ser operados es: 1. 2. 3. 4. 5. 6. 7. 8. Lectura Read(Archivo, TipoDeDato) En el caso de ser un registro se lee completo. Grabar Write(NombreInterno, TipoDeDato) Seek(NombreInterno,Posición), Ubica el Puntero a Pos Registros desplazados desde el inicio del mismo Flesize(NombreInterno) Indica cantidad de registros. Filepos(NombreInterno) retorna la posición actual del puntero. Tambien cantidad de registros de desoplazamiento desde el inicio del archivo. Tanto filepos como filesize retonan un tipo de dato entero largo, pero pueden ser contenido en un entero de menor jerarquia mientras no se produzca desbordamiento del mismo. EOF(NombreInterno) Retorna true si se alcanzo la marca de fin de archivo y False en caso contrario. Truncate(NombreInterno) pone la marca de fin de archivo en el lugar donde esta el puntero. Trunca el archivo program ConvierteTextoABinario; Type TipoRegistro = Record Numero : Integer; Cadena : string[10]; End; TipoArchivo = FILE OF TipoRegistro; var Arch : text; Registro : TipoRegistro; Binario : TipoArchivo; I : Integer; begin clrscr; Assign (Arch,'C:\borlandc\archivo.txt'); Reset(Arch); Assign (Binario,'C:\...\Binario.Dat'); Rewrite(Binario); while not EOF(Arch) do begin {Lectura con formato en regitrode un archico de texto y lo almacena en un archivo binario} readln(Arch, Registro.Numero, Registro.Cadena); write(Binario,Registro); end; Close(Arch); Close(Binario); End. program RecorrerBinario; uses crt; Type TipoRegistro = Record Numero : Integer; Cadena : string[10]; End; TipoArchivo = FILE OF TipoRegistro; var Arch : text; Registro : TipoRegistro; Binario : TipoArchivo; begin Assign (Binario,'C:\...\Binario.Dat'); Reset(Binario); while not EOF(Binario) do begin {Lectura con formato en regitro del archivo Binario} read(Binario, Registro); writeln('El entero del Bin.: ', Registro.Numero:8); writeln('El texto del Bin. : ', Registro.Cadena:8); end; Close(Binario); end. program RecorreBinarioInverso; Type TipoRegistro = Record Numero : Integer; Cadena : string[10]; End; TipoArchivo = FILE OF TipoRegistro; Var Binario : TipoArchivo; Registro : TipoRegistro; I : Integer; Begin Assign (Binario,'C:\...\Binario.Dat'); Reset(Binario); For i := FileSize(Binario) - 1 downto 0 do begin {Lectura con formato en regitro del archivo Binario en orden inverso} Seek(Binario,I); read(Binario, Registro); writeln('El entero del Bin.: ', Registro.Numero:8); writeln('El texto del Bin. : ', Registro.Cadena:8); end; Close(Arch); Close(Binario); end. Ejemplo en C con aplicaciones de estructuras enlzadas /* Toma una cadena que representa una expresión aritmética y la convierte a notación sufijo usando procedimientos de pilas*/ #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef char TipoInfo; typedef struct tiponodo { TipoInfo Info; struct tiponodo *sgte; } TipoNodo; typedef TipoNodo* TipoPuntero; void Meter(TipoPuntero *pila , TipoInfo valor); void Sacar(TipoPuntero *pila , TipoInfo *valor); void Sufijo(char * cadena, char * suf); int main() { char cad1[10]; clrscr(); Sufijo("5*8+3",cad1); printf("%s\n", cad1); getchar(); return 0; } void Sufijo(char * cadena, char * suf) { char c; int i = 0,j=0; TipoPuntero pila=NULL; c = cadena[i]; while (c) { switch(c) { case '+': case '-': case '*': case '(': case '/': Meter(&pila, c); break; case ')': Sacar(&pila, &c); while (c != '(') { suf[j++] = c; Sacar(&pila, &c); } break; default : suf[j++]= c; break; } i++; c=cadena[i]; } while(pila){ Sacar(&pila,&c); suf[j++]=c; } suf[j] = '\0'; } void Meter(TipoPuntero *pila , TipoInfo valor) { TipoPuntero ptr; ptr =(TipoPuntero) malloc(sizeof(TipoNodo)); ptr -> Info = valor; ptr -> sgte = *pila; *pila = ptr; } void Sacar(TipoPuntero *pila , TipoInfo *valor) { TipoPuntero ptr; ptr = *pila; *pila = (*pila)->sgte; *valor = ptr->Info; free(ptr); } ANEXO 1 Representaciones gráficas de algoritmos Diagrama de Nassi-Sneiderman Condición 1 T F Acción 1 Acción 5 Acción 2 Mientras condición 3 Condición 2 T Acción 6 F Acción 3 Acción 7 Acción 8 Acción 9 Acción 4 Acción 10 Acción 11 Acción 12 Repetir hasta condición 4 Diagramas de Jackson Diagramas de Lindsay. PASCAL DIAGRAMA DE DETALLE Variable ← expresión Variable = expresión READ (var1, var2,....var n) var1, var2,.... WRITELN var 1 var 2 (ó ó , ..... ) WRITE liter1 liter2 var 1 ó liter1 IF condición THEN sentencia 1 ELSE sentencia 2 ,.... liter2 Condición Instrucción 1 Instrucción 2 Condición WHILE condición DO sentencia Instrucción REPEAT sentencia; : : sentencia n UNTIL condición FOR variable: expres1 ó var 2 ó Instrucción 1 : : Instrucción n Condición TO expres2 DOWNTO Var: exp1, exp2 Instrucción DO sentencia CASE expresión OF const1....... const n : instrucción1 : : const1...... const p : instrucción m END Cualquier sentencia puede ser reemplazada por un bloque: BEGIN sentencias 1; : : sentencias n END Expresión Const1... Const n Const1... Const p Instrucción1 Instrucción m Correspondiendo en el diagrama de detalle la secuencia: instrucción 1; : : instrucción n Llaves de Warniel HacerUnaCosa) Si Condición Exclusión No 1 Algoritmo Case Ordinal Mientras Condición HacerOtraCosa Vacio 2 HacerUnaCosa; HacerOtraCosa; HacerAlgoMas Notación Algoritmica LEXICO {Léxico Global del algoritmo} {Declaración de tipos, constantes, variables y acciones} Acción 1 PRE {Precondición de la acción 1} POS {Poscondición de la acción 1} LEXICO {Léxico local, propio de la acción 1} Declaraciones locales ALGORITMO {Implementación de la acción 1} {Secuencia de instrucciones de la acción 1} FIN {Fin implementación algoritmo de la acción 1} ALGORITMO PRE {Precondición del algoritmo principal} POS {Poscondición del algoritmo principal} {Secuencia de instrucciones del algoritmo principal} FIN {Fin del algoritmo principal} Equivalencias entre notación algorítmica y lenguajes de programación CONDICIONAL Formato SI Condicion ENTONCES S SI_NO R FIN_SI Pascal If expresion condicional Then S Else R; C If (expresion) S; Else R; Formato SEGÚN expr V1 : S1 V2 : S2 EN_OTRO_CASO : Sn FIN_SEGÚN Pascal Case selector of Valor1 : S1; ......................... else Ve: Se; end; C switch (selector) { case etiqueta:S; break; .............................. default: R; } ITERACION Formato Mientras Cond. Hacer S FIN_MIENTRAS Pascal While Expresion logica do S; C while(expresion) S; Formato REPETIR S HASTA Cond Efecto Repeat S Until expresion logica do S; while(expresion) Formto PARA i [Vi..Vf] HACER S FIN_PARA Efecto For i:=Vi to vf do S; C for(i=0;i<vf;i++) S; Estilos de Indentación Recomendacion de estilos de indentacion para desarrollos más claros y legibles.(Ing. J. M. Sola) Estilo The One True Brace Style while( SeaVerdad() ) { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); BSD/Allman. while( SeaVerdad() ) { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); Estilo Whitesmiths while( SeaVerdad() ) { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); Estilo GNU while( SeaVerdad() ) { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); Estilo Pico while( SeaVerdad() { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); Estilo Banner while( SeaVerdad() ) { HacerUnaCosa(); HacerOtraCosa(); } HacerUnaUltimaCosaMas(); BIBLIOGRAFIA Behrouz Forouzan. Introducción a la ciencia de la computación. 2005. Ciencias e Ingenieria. De Giusti. Algoritmos datos y programas. 2001. Prentice Hall. Garcia Molina. Una introducción a la programación. 2005. Thomson. Kernighan - Ritchie. El lenguaje de programacion C. 1988. Pearson Kerighan – Pike. La practica de la programacion. 2000. Pearson Perkins David. La bañera de Arquimedes y otras historias del descubrimiento cientifico. Paidos 2004 Iranzo, j. Logica simbolica para informaticos. 2006. Alfaomega. Perez M. Matematica discreta y algoritmos. 2005. Answer. Joyanes Aguilar, L.Algoritmos y estructura de datos, una perspectiva en C. 2004 Mc Graw Hill El Autor Oscar Ricardo Bruno Formación Academica Licenciado en Sistemas (Instituto Tecnologico de Buenos Aires) Magíster en Docencia Universitaria UTN FRBA Especialista en Ingenieria en Sistemas (Maestrando) UTN FRBA Especialista en Docencia Universitaria UTN FRBA Profesor en Docencia Universitaria en Sistema INSPT UTN FRBA Espeialista en Investigación Operativa ESIO DIGID Actividad Docente Profesor Adjunto Algoritmos y Estructura de Datos y Sintaxis y Semántica de Lengujes UTN FRBA . Profesor Adjunto Estructura de Datos Univeridad del Salvador Profesor Programación II CENT 24. Profesor Titular Laboratorio II y III Escuela Tecnica Nro 1 Otto Krause Coordinador Area Computación EIOK Director y jurado de tesis UTN FRBA Ex Consejero Departamental docente UTN FRBA departamento Sistemas. Menciones Finalista premios Sadosky 2006 a la inteligencia argentina categoría calidad docente