Estructura de datos en C

Iniciado por Pizzerino, 4 Abril 2018, 19:43 PM

0 Miembros y 1 Visitante están viendo este tema.

Pizzerino

Buenas, soy nuevo en este foro. Llevo tomando el curso de Programación desde que tengo 17, ahora teniendo 20 y estando en la uni se me dificulta mucho esta materia [Estructura de Datos y Algoritmos], apartir de los temas de Pilas, Colas, Listas ya me perdí completamente. He tomado libros al respecto, internet igual pero no me queda claro. Veo como se definen pero no entiendo, ¿alguna recomendación? o será que está tan fácil que no lo visualizo.

Saludos ;-)

MAFUS

Son muchos conceptos así que ¿qué parte no entiendes?
¿Su concepto?
¿Los punteros?
¿Cómo se funcionan?
¿Cómo se desarrollan?

Lo digo porque sabes, a lo mejor, sabes que es una pila pero como fallas en punteros no ves como se desarrolla o sabes de punteros pero no ves diferencia entre pila y lista enlazada.
¿Qué te falla?

srWhiteSkull

No entiendo la gente que hace una carrera de una materia que desconocen completamente,

Para que entiendas lo mínimo cógete el navegador Chrome, vete a la consola, con F12, y en la misma terminal escribe lista=[] pulsa enter y luego escribe lista.push([]) y pulsa nuevamente enter, luego escribe lista[0].push([]) y pulsa enter y luego escribe lista[0].push("hola y adios") y pulsa enter y por último lista.push(lista) pulsa enter y escribe lista y al pulsar enter analiza el árbol del contenido y despliega sus ramas  :xD eso es una lista enlazada, ahora aplícalo con los amigables punteros en vez de referencias... pero como dice MAFU, es importante saber que es un puntero, como funciona, como se declara etc... para pasar a cosas mayores.

Kenji-chan


dijsktra

#4
 Uff! El tema es muy denso para explicar en un sólo mensaje. Pero
vamos a intentarlo. Intenta, en un primer momento, olvidar que sabes
C/C++ o cualquier otro lenguaje.

 Sabes, desde los 10 años, que los enteros ( o los naturales,
racionales) son un tipo de números dotados de ciertas operaciones (la
suma, el producto...).  Allá por el último cuarto del siglo XIX, los
matemáticos europeos (Dedekind, Hilbert, Noether, Peano, Cantor y
otros... ) intentaban caracterizar las propiedades de esos "entes" y
sus operaciones. Te sonaran las propiedades commutativa, asociativa,
y algún valor especial como el elemento neutro,

sets
int
operations
+ : (int, int) -> int
constants
0 : int
axioms
a + b = b + a  [comm]
(a + b) + c = a + (b + c)  [assoc]
a + 0 = a  [e.neutro]
....


y los términos anillo, semigrupo, grupo conmutativo...

En computación, esos enteros y sus operaciones tienen una
representación trivial y limitada en el computador (int, con MAX_INT,
etc...)  que se proyecta en palabras de 8 o 16 bits y operaciones
básicas en la ALU...

Sin embargo, en algoritmia se necesitan además otros "tipos de
datos", como los que mencionas, (pila, cola, listas...) que también
se caracterizan por unas propiedades. Éstas también se pueden
expresar algebraicamente (aunque ya casi nadie lo practica, :-( )

En el caso de las pilas de enteros (stack), la estructura lineal más
sencilla, tenemos 3/4 operaciones.

Las operaciones, grosso modo, se dividen en tres grupos.
- constructoras
- modificadoras
- consultoras.


sets
stack, int, bool
constants
empty : stack
operations
push : (stack,int) -> stack
pop  : stack - -> stack
head : stack - -> int
isempty : stack -> bool
var
i : int
p : stack
axioms
pop(push(p,i))=p
head(push(p,i))=i
isempty(empty)=true
...


El primer axioma dice que al quitar (pop) un elmento de una pila (p)
a la que por lo menos se le ha añadido (push) un entero (i), nos
queda esa pila sin el elemento. Esto también lo sabes "por sentido
común", pero la novedad, repito, es la forma matemática, cuyo origen
debemos a los europeos del finales del s. XIX.


Y aquí entra el lenguaje C. Como no están implementadas a nivel
hardware, el lenguaje nos permite "simularlas" (ojo a la palabra, es
clave) con construcciones que tienen su base en elementos conocidos,
como arrays, punteros...


Los que programan la STL de C++ las ponen a tu disposición una serie
de estructuras (<stack>, <queue>, <list>) para que las uses en tus
algoritmos. Son de muy alta calidad y su implementación escapa a la
de cualquier principiante.

Pero podemos experimentar haciéndo las nuestras "de juguete".

- Para empezar, lo haremos con memoria estática, (arrays...)  

- En otro correo, si quieres, las podemos hacer con memoria dinámica
(punteros)

Observa que, al igual que con los int, al usar una array fijo de
elementos, la expresividad de nuestra implementación esta limitada a
un número maximo de elementos apilados.  

Al margen de esto, una operación no es aplicable siempre, como la
división por 0. Es el caso de la operación pop, o head. No son aplicables
sobre pilas vacías

En esos casos, su comportamiento está indefinido, por eso se emplea
la libreria <assert.h>.


#ifndef _STACK_TOY_
#define _STACK_TOY_
#define MAXIMUM 200

#include <assert.h>

typedef struct
{
 // I : 0 <= many <= MAXIMUM
 unsigned int many;
 unsigned int M[MAXIMUM];
} STACK, *PSTACK;

void empty( PSTACK pstack)
{
 pstack->many = 0 ;
}

void push(PSTACK pstack, const int i)
{
 assert((pstack->many)<MAXIMUM);
 pstack->M[pstack->many++]=i;
 return;
}

void pop(PSTACK pstack)
{
 assert((pstack->many)>0);
 pstack->many--;
 return;
}


int head(const PSTACK pstack)
{
 assert((pstack->many)>0);
 return pstack->M[pstack->many -1];
}

int isempty(const PSTACK pstack)
{
 return  (pstack->many == 0 );
}

 
#endif


Si la depuración es el proceso de eliminar fallos en el software, entonces programar debe ser el proceso de ponerlos dentro. (Edsger Dijsktra)