estructura de datos.docx

9
Estructura de datos En programación, una estructura de datos es una forma de organizar un conjunto de datos elementales con el objetivo de facilitar su manipulación. Un dato elemental es la mínima información que se tiene en un sistema. Una estructura de datos define la organización e interrelación de éstos y un conjunto de operaciones que se pueden realizar sobre ellos. Las operaciones básicas son: Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Búsqueda, encontrar un determinado valor en la estructura para realizar una operación con este valor, en forma secuencial o binario (siempre y cuando los datos estén ordenados). Otras operaciones que se pueden realizar son: Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que contenga a las apareadas. Cada estructura ofrece ventajas y desventajas en relación a la simplicidad y eficiencia para la realización de cada operación. De esta forma, la elección de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operación sobre los datos. Puntero Un puntero o apuntador es una variable que referencia una región de memoria; en otras palabras es una variable cuyo valor es una dirección de memoria. Si se tiene una variable ' p ' de tipo puntero que contiene una dirección de memoria en la que se encuentra almacenado un valor ' v ' se dice que ' p ' apunta a ' v '. El programador utilizará punteros para guardar datos en memoria en muchas ocasiones, de la forma que se describe a continuación.

Upload: chrisfer82

Post on 24-Nov-2015

14 views

Category:

Documents


1 download

TRANSCRIPT

Estructura de datosEn programacin, una estructura de datos es una forma de organizar un conjunto de datos elementales con el objetivo de facilitar su manipulacin. Un dato elemental es la mnima informacin que se tiene en un sistema.Una estructura de datos define la organizacin e interrelacin de stos y un conjunto de operaciones que se pueden realizar sobre ellos. Las operaciones bsicas son: Alta, adicionar un nuevo valor a la estructura. Baja, borrar un valor de la estructura. Bsqueda, encontrar un determinado valor en la estructura para realizar una operacin con este valor, en forma secuencial o binario (siempre y cuando los datos estn ordenados).Otras operaciones que se pueden realizar son: Ordenamiento, de los elementos pertenecientes a la estructura. Apareo, dadas dos estructuras originar una nueva ordenada y que contenga a las apareadas.Cada estructura ofrece ventajas y desventajas en relacin a la simplicidad y eficiencia para la realizacin de cada operacin. De esta forma, la eleccin de la estructura de datos apropiada para cada problema depende de factores como la frecuencia y el orden en que se realiza cada operacin sobre los datos.

PunteroUn puntero o apuntador es una variable que referencia una regin de memoria; en otras palabras es una variable cuyo valor es una direccin de memoria. Si se tiene una variable ' p ' de tipo puntero que contiene una direccin de memoria en la que se encuentra almacenado un valor ' v ' se dice que ' p ' apunta a ' v '. El programador utilizar punteros para guardar datos en memoria en muchas ocasiones, de la forma que se describe a continuacin. [Memoria] | . | | . | | . | ----- |---------| | p |--->| v | ----- |---------| | . | | . | | . |Trabajar con punteros implica la no manipulacin de los datos en s, sino manejar las direcciones de memoria en la cuales estos residen.Los punteros son de amplia utilizacin en programacin y muchos lenguajes permiten la manipulacin directa o indirecta de los mismos. La razn de ser principal de los punteros reside en manejar datos alojados en la zona de memoria dinmica o heap (aunque tambin se pueden manipular objetos en la zona esttica), bien sean datos elementales, estructuras (struct en C) u objetos pertenecientes a una clase (en lenguajes Orientados a Objetos). Gracias a esta propiedad, los punteros permiten modelar un grafo, en donde los elementos de ste son los datos residentes en memoria y las relaciones entre los elementos son los propios apuntadores.En nuevos lenguajes de alto nivel, los punteros se han tratado de abstraer. De tal forma que en el lenguaje C# slo pueden ser usados en zonas de cdigo delimitadas como "inseguras", o llegando a su total desaparicin del cdigo en lenguajes como Java o Eiffel.Que no estn en el cdigo no implica que no existan: internamente, la Mquina Virtual Java trata todas las variables que referencian objetos como punteros a zonas de memoria que realmente contienen los objetos. Esto puede causar ciertos efectos laterales si no se tiene en cuenta. De hecho, no es descabellado pensar que Java est utilizando punteros si cuando uno accede a una propiedad de un objeto no inicializado es lanzada la excepcin NullPointerException.

Ejemplo de uso de punteros en una estructura en CEl ejemplo que sigue es propio del lenguaje C/C++ y no es de aplicacin en otros lenguajes de programacin: struct Elemento // Ejemplo de un nodo de lista doble enlazada { int dato; struct Elemento *siguiente; // El '*' es el operador de indireccin, y es el usado para declarar punteros struct Elemento *anterior; };Para acceder a los atributos como punteros de una estructura que va a ser tratada como tal, se debe des-referenciar el puntero y acceder a sus miembros como se hara con una variable normal, o usar directamente el operador: ->. De tal modo que: Elemento *elem; Elemento sig1 = (*elem).siguiente; Elemento sig2 = elem->siguiente; /* Se cumple que: sig1==sig2 */

Los parntesis en este ejemplo son necesarios, pues el operador '*' es el que menor prioridad de operaciones tiene asignada (por lo que se hara *(elem.siguiente), lo que es incorrecto, pues tratara acceder a un campo de una direccin de memoria, y no de una estructura. Esto es un error sintctico, en tiempo de compilacin).

Otro ejemplo en C++ void swap(int *x, int *y) { int temp; temp = *x; // copia el valor apuntado por x a temp *x = *y; // copia el valor apuntado por y en la ubicacin del puntero x *y = temp; // copia el valor de temp en la ubicacin apuntada por y }

Ejemplo en C# //Suma de dos nmeros enteros private unsafe int Suma(int* a, int* b) { return *a + *b; } // Su uso (El mtodo llamador tambin debe tener la palabra clave 'unsafe'): // int x, y; // int *ptr1 = &x; // int *ptr2 = &y; // Suma(ptr1, ptr2);

Descriptor de archivoEn informtica los trminos descriptor de archivo o descriptor de fichero son usados generalmente en sistemas operativos POSIX.En la terminologa de Microsoft Windows y en el contexto de la biblioteca stdio, se prefiere el trmino "manipulador de archivos" o "manipulador de ficheros", ya que es tcnicamente un objeto diferente.En POSIX, un descriptor de archivo es un entero, especficamente del tipo int de C. Hay 3 descriptores de archivo estndar de POSIX que presumiblemente tiene cada proceso, salvo quiz los demonios:Valor enteroNombre

0Entrada estndar (stdin)

1Salida estndar (stdout)

2Error estndar (stderr)

Generalmente, un descriptor de archivo es una clave a una estructura de datos residente en el ncleo, que contiene detalles de todos los archivos abiertos. En POSIX, esta estructura de datos se llama "tabla de descriptores de archivos", y cada proceso tiene la suya. La aplicacin que lanza un usuario pasa al ncleo la clave abstracta mediante una llamada al sistema, y el ncleo tendr acceso al archivo a nombre de la aplicacin, que se basar en la clave. Esa misma aplicacin no puede acceder a la tabla de descriptores de archivo directamente, ni para leer ni para escribir.En los sistemas Unix, los descriptores de archivo se pueden referir a archivos, directorios, dispositivos de bloques o dispositivos de caracteres (tambin llamados "archivos especiales"), sockets, FIFOs (tambin llamados "tuberas con nombre") o tuberas sin nombre.El manejador de archivos en las rutinas de la biblioteca stdio de Unix es, tcnicamente, un puntero o una direccin a la primera capa de administracin de una interfaz adicional (la interfaz al flujo de archivo stdio), que se apila encima del descriptor de archivo de bajo nivel real. Como "manejador de archivo" se refiere a esta interfaz adicional, no es intercambiable por "descriptor de archivo".

Punteros en JAVAHay un par de ideas sobre java muy extendidas: java no tiene punteros y en java todo se pasa por referencia. La nocin de puntero es innata en Java, todos los objetos son punteros, como ya se sabe no es suficiente con definirlos sino hay que construirlos dinmicamente con la sentencia new y si es necesario pasar algunos parmetros al constructor.La realidad, es que java se entiende mucho mejor si lo pensamos exactamente al revs. En java slo hay punteros (con excepcin de los tipos primitivos) y en java todo se pasa por valor (por copia).Por ejemplo, en C++ hacemos esto MiClase a;y ya est todo correcto. La variable a est perfectamente inicializada. Si en java hacemos eso, tenemos una variable a sin inicializar. Es necesario hacerle un new, exactamente igual que un puntero en C++MiClase a = new MiClase(); // Esto en JavaMiClase *a = new MiClase(); // Esto en C++// o este otro tipo de inicializacin extraamente parecida ...MiClase a = null; // en javaMiClase *a=NULL; // en C++

La nica diferencia es la notacin con el asterisco. Si pensamos que en java TODO son punteros, no es necesario poner el asterisco para distinguir lo que es puntero de lo que no lo es, por lo que simplemente lo han quitado.Ahora imaginemos un mtodo que recibe una clase y que le hacemos una llamada // en java... void medodo (MiClase a) {a = new MiClase(); }...MiClase b = null; metodo (b);

Bueno, pues cuando salimos del mtodo b sigue valiendo null, "apuntando a null". Eso quiere decir que a y b son variables distintas, es decir, se ha pasado la variable b por valor al mtodo.

Para crear una nueva instancia y devolverla, en java no queda ms remedio que hacerlo en el return, es imposible hacerlo a travs de parmetros. Sin embargo, en C++ tenemos ms posibilidades. Podemos usar un puntero al puntero, es decir, hacer esto void metodo (MiClase **a) {*a = new MiClase(); }...MiClase *b=NULL; metodo (&b);o bien, incluso usar referencias de verdad // El & en la declaracin es lo que hace que realmente sea una referencia. void metodo (MiClase * &a) {a=new MiClase(); }...MiClase *b=NULL; metodo (b); // Aqui b apunta al MiClase creado dentro del mtodo.Hacindolo as, el puntero b de fuera del mtodo y el puntero a del parmetro son exactamente la misma variable. Ojo, no quiero decir que sean dos punteros distintos que apunten al mismo lado, sino que son realmente el mismo puntero. Cuando hacemos que a apunte a otro sitio, b tambin apuntar al mismo sitio. Esto es lo que yo entiendo realmente por referencia. Vemos en este sentido que C++ nos da ms posiblidades que java. La terminologa utilizada en estos lenguajes, a veces es la misma, pero hay grandes diferencias subyacentes en su significado, como se ha recalcado a lo largo de esta seccin.C tiene tipos de datos bsicos y punteros. C++ modifica un poco este panorama y le aade los tipos referencia. Java tambin especifica sus tipos primitivos, elimina cualquier tipo de punteros y tiene tipos referencia mucho ms claros.Todo este maremgnum de terminologa provoca cierta consternacin, as que los prrafos que siguen intentan aclarar lo que realmente significan los trminos que se utilizan.Se conocen ya ampliamente todos los tipos bsicos de datos: datos base, integrados, primitivos e internos; que son muy semejantes en C, C++ y Java; aunque Java simplifica un poco su uso a los desarrolladores haciendo que el chequeo de tipos sea bastante ms rgido. Adems, Java aade los tipos boolean y hace imprescindible el uso de este tipo booleano en sentencias condicionales.C y C++ permiten la declaracin y uso de punteros, que pueden ser utilizados en cualquier lugar. Esta tremenda flexibilidad resulta muy til, pero tambin es la causa de que se pueda colgar todo el sistema.La intencin principal en el uso de los punteros es comunicarse ms directamente con el hardware, haciendo que el cdigo se acelere. Desafortunadamente, este modelo de tan bajo nivel hace que se pierda robustez y seguridad en la programacin y hace muy difciles tareas como la liberacin automtica de memoria, la desfragmentacin de memoria, o realizar programacin distribuida de forma clara y eficiente.Las referencias se incorporaron a C++ en un intento de manejar punteros de C de forma ms limpia y segura. Sin embargo, como no elimina los punteros, la verdad es que su propsito lo consigue a medias. Es ms, se podra decir que con las referencias C++, el lenguaje se vuelve ms complicado y no es ms poderoso que antes. Las referencias deben ser inicializadas cuando se declaran y no se pueden alterar posteriormente. Esto permite incrementar la eficiencia en tiempo de ejecucin sobre la solucin basada en punteros, pero es ms por las deficiencias de los punteros que por las ventajas de las referencias. Ejemplo: int *puntero; ...... puntero++; // puntero apunta al siguiente entero en la RAM.La nica forma de hacer que un puntero haga referencia a otra posicin de memoria (instancia) es asignarlo a un objeto creado con la sentencia new o usando el operador = y asignar otra rea de memoria a dicho objeto. Ejemplo: String cadena1=new String("Hola Mundo"); String cadena2=new String("Esta es una cadena con siete palabras"); ........ cadena1=cadena2;En este caso el objeto cadena1 que tiene una referencia a una instancia de la clase String que contiene la cadena "Hola Mundo" es asignado a una instancia de String que contiene la cadena "Esta es una cadena con siete palabras", quedando liberada la memoria ocupada por la primera instancia de String que estaba asignada al objeto cadena1, despus de la asignacin los dos objetos cadena1 y cadena2 apuntan (hacen referencia) a la misma instancia de la clase String que contiene la cadena "Esta es una cadena con siete palabras".

7