• Ir al contenido
  • Ir a la navegación
  • Ir al buscador
 
Portada Boludo
ING English
Directorio WAP para móvil, Tablet, iPhone o Smartphone

Centro de Noticias de la Universidad de Oriente

Categorías

 

Inicio  |  Contacto  |  Posts  |  TIENDA PUBLISHOP  |  Sobre nosotros  |  Registro y Planes  |  Pagos  |  Donaciones

Ver Código QR de esta página

Campaña #AyudemosaYuli  |  Campaña #AyudemosaStephany.  |  ¿Interesado(a) en cursos y resolución de ejercicios de materias prácticas? Para más información, contáctenos por: Teléfono: +58 (412) - 8226575. WhatsApp y Telegram: +58 (426) - 6836955 o escriba al correo: [email protected]. Únete al grupo: SISTEMAS (UDOMO).

[»] **Musica para tu celular

WEB TRANSLATOR

LINK for English Language

Use this link for translate into English


+ Buscar en BolUDO

 

Estructuras dinámicas en C++: Listas genéricas circulares

Tweet
 

lunes julio 11, 2016

Una lista circular simplemente encadenada la podemos representar gráficamente:

lista circular simplemente encadenada en C++

Observemos que el puntero sig del último nodo apunta al primer nodo. En este tipo de listas si avanzamos raiz no perdemos la referencia al nodo anterior ya que es un círculo.

Una lista circular puede también ser doblemente encadenada:

lista circular doblemente encadenada en C++

El puntero ant del primer nodo apunta al último nodo de la lista y el puntero sig del último nodo de la lista apunta al primero.

Resolveremos algunos métodos para administrar listas genéricas circulares doblemente encadenadas para analizar la mecánica de enlace de nodos.

Programa:

#include <iostream>

using namespace std;

class ListaCircular {
private:
    class Nodo {
    public:
        int info;
        Nodo *sig;
        Nodo *ant;
    };

    Nodo *raiz;
public:
    ListaCircular();
    ~ListaCircular();
    void insertarPrimero(int x);
    void insertarUltimo(int x);
    bool vacia();
    void imprimir();
    int cantidad();
    void borrar(int pos);
};

ListaCircular::ListaCircular()
{
    raiz = NULL;
}

ListaCircular::~ListaCircular()
{
    if (raiz != NULL) {
        Nodo *reco = raiz->sig;
        Nodo *bor;
        while (reco != raiz)
        {
            bor = reco;
            reco = reco->sig;
            delete bor;
        }
        delete raiz;
    }
}

void ListaCircular::insertarPrimero(int x)
{
    Nodo *nuevo = new Nodo();
    nuevo->info = x;
    if (raiz == NULL) 
    {
        nuevo->sig = nuevo;
        nuevo->ant = nuevo;
        raiz = nuevo;
    }
    else 
    {
        Nodo *ultimo = raiz->ant;
        nuevo->sig = raiz;
        nuevo->ant = ultimo;
        raiz->ant = nuevo;
        ultimo->sig = nuevo;
        raiz = nuevo;
    }
}

void ListaCircular::insertarUltimo(int x) 
{
    Nodo *nuevo = new Nodo();
    nuevo->info = x;
    if (raiz == NULL) 
    {
        nuevo->sig = nuevo;
        nuevo->ant = nuevo;
        raiz = nuevo;
    }
    else 
    {
        Nodo *ultimo = raiz->ant;
        nuevo->sig = raiz;
        nuevo->ant = ultimo;
        raiz->ant = nuevo;
        ultimo->sig = nuevo;
    }
}

bool ListaCircular::vacia()
{
    if (raiz == NULL)
        return true;
    else
        return false;
}

void ListaCircular::imprimir()
{
    if (!vacia()) {
        Nodo *reco = raiz;
        do {
            cout<<reco->info  <<"-";
            reco = reco->sig;
        } while (reco != raiz);
        cout << "";
    }
}

int ListaCircular::cantidad()
{
    int cant = 0;
    if (!vacia()) 
    {
        Nodo *reco = raiz;
        do {
            cant++;
            reco = reco->sig;
        } while (reco != raiz);
    }
    return cant;
}

void ListaCircular::borrar(int pos)
{
    if (pos <= cantidad())
    {
        if (pos == 1) 
        {
            if (cantidad() == 1) 
            {
                delete raiz;
                raiz = NULL;
            }
            else 
            {
                Nodo *bor = raiz;
                Nodo *ultimo = raiz->ant;
                raiz = raiz->sig;
                ultimo->sig = raiz;
                raiz->ant = ultimo;
                delete bor;
            }
        }
        else {
            Nodo *reco = raiz;
            for (int f = 1; f <= pos - 1; f++)
                reco = reco->sig;
            Nodo *bor = reco;
            Nodo *anterior = reco->ant;
            reco = reco->sig;
            anterior->sig = reco;
            reco->ant = anterior;
            delete bor;
        }
    }
}



void main()
{
    ListaCircular *lc = new ListaCircular();
    lc->insertarPrimero(100);
    lc->insertarPrimero(45);
    lc->insertarPrimero(12);
    lc->insertarPrimero(4);
    cout <<"Luego de insertar 4 nodos al principio";
    lc->imprimir();
    lc->insertarUltimo(250);
    lc->insertarUltimo(7);
    cout<<"Luego de insertar 2 nodos al final";
    lc->imprimir();
    cout<<"Cantidad de nodos:" <<lc->cantidad() <<"";
    cout <<"Luego de borrar el de la primer posición:";
    lc->borrar(1);
    lc->imprimir();
    cout << "Luego de borrar el de la cuarta posición:";
    lc->borrar(4);
    lc->imprimir();
    delete lc;
    cin.get();
}

Este proyecto lo puede descargar en un zip desde este enlace :

ListaCircular.zip

Para insertar al principio de una lista circular doblemente encadenada:


    void insertarPrimero(int x) {

Creamos un nodo y guardamos la información:


Si la lista está vacía luego tanto el puntero sig y ant apuntan a si mismo ya que debe ser circular (y raiz apunta al nodo creado):

   if (raiz == NULL) 
    {
        nuevo->sig = nuevo;
        nuevo->ant = nuevo;
        raiz = nuevo;
    }
 

En caso que la lista no esté vacía disponemos un puntero al final de la lista (el puntero ant del primer nodo tiene dicha dirección):

    else 
    {
        Nodo *ultimo = raiz->ant;
 

El nodo a insertar lo enlazamos previo al nodo apuntado por raiz:

        nuevo->sig = raiz;
        nuevo->ant = ultimo;
        raiz->ant = nuevo;
        ultimo->sig = nuevo;
        raiz = nuevo;

Finalmente hacemos que raiz apunte al nodo creado luego de haber hecho todos los enlaces:

        raiz=nuevo;

Para insertar un nodo al final de la lista:


    void insertarUltimo(int x) 

El algoritmo es idéntico al método que inserta al principio con la salvedad que no desplazamos raiz con la dirección del nodo creado (es decir al insertar en la posición anterior del primer nodo lo que estamos haciendo realmente es insertar al final de la lista):

void ListaCircular::insertarUltimo(int x) 
{
    Nodo *nuevo = new Nodo();
    nuevo->info = x;
    if (raiz == NULL) 
    {
        nuevo->sig = nuevo;
        nuevo->ant = nuevo;
        raiz = nuevo;
    }
    else 
    {
        Nodo *ultimo = raiz->ant;
        nuevo->sig = raiz;
        nuevo->ant = ultimo;
        raiz->ant = nuevo;
        ultimo->sig = nuevo;
    }
}

Para imprimir la lista ya no podemos disponer un puntero reco que apunte al primer nodo y que se detenga cuando encuentre un nodo que el atributo sig almacene NULL.


void imprimir ()

Si la lista no está vacía disponemos un puntero en el primer nodo y utilizamos un do/while para recorrer la lista. La condición del do/while es que se repita mientras el puntero reco sea distinto a raiz (es decir que no haya dado toda la vuelta a la lista):

void ListaCircular::imprimir()
{
    if (!vacia()) {
        Nodo *reco = raiz;
        do {
            cout<<reco->info  <<"-";
            reco = reco->sig;
        } while (reco != raiz);
        cout << "";
    }
}

Para borrar el nodo de una determinada posición:


    void borrar (int pos)

Debemos primero identificar si es el primero de la lista (ya que en este caso se modifica el puntero externo raiz):

if (pos <= cantidad())
    {
        if (pos == 1) 
    

Si es el primero y el único de la lista hacemos que raiz apunte a NULL y borramos el nodo:

            if (cantidad() == 1) 
            {
                delete raiz;
                raiz = NULL;
            }

Si no disponemos un puntero al final de la lista, avanzamos raiz y enlazamos el último nodo con el segundo de la lista:

 
                Nodo *bor = raiz;
                Nodo *ultimo = raiz->ant;
                raiz = raiz->sig;
                ultimo->sig = raiz;
                raiz->ant = ultimo;
                delete bor;

En caso que queremos borrar un nodo que se encuentra en medio de la lista o inclusive al final debemos recorrer con un for hasta el nodo que queremos borrar y luego disponemos un puntero en el nodo anterior y otro puntero en el nodo siguiente. Seguidamente procedemos a enlazar los nodos:

            Nodo *reco = raiz;
            for (int f = 1; f <= pos - 1; f++)
                reco = reco->sig;
            Nodo *bor = reco;
            Nodo *anterior = reco->ant;
            reco = reco->sig;
            anterior->sig = reco;
            reco->ant = anterior;
            delete bor;
ListaCircular::~ListaCircular()

Para borrar todos los nodos de la lista en el destructor mediante un ciclo repetitivo avanzamos a partir del segundo nodo de la lista mientras el puntero reco sea distinto a la dirección del primer nodo:

        Nodo *reco = raiz->sig;
        Nodo *bor;
        while (reco != raiz)
        {
            bor = reco;
            reco = reco->sig;
            delete bor;
        }

Cuando salimos de la estructura repetitiva eliminamos el último nodo que nos queda que es el primero de la lista, utilizamos el mismo puntero raiz para eliminarlo:

        delete raiz;
 
}
— @bolUDOoficial

— Síguenos en Twitter@bolUDOoficial

Categorías: #C++, #


[0] Atrás | Directorio
« Inicio
Apps Infoudo
Apps Infoudo ¡Descarga el icono directo en el menú de tu equipo!
[»] Las mejores Apps para tu celular
[»] Imágenes Gratis


Comenta o lee lo que otros opinan

COMPÁRTELO:

Indica que te gusta y comparte

Me Gusta :)Facebook Tuiteame :)Twitter .WhatsApp .Telegram . LinkedIn

También te puede interesar:

NOCIONES BÁSICAS DE LA PROGRAMACIÓN ORIENTADA A OBJETOS.
Material de Apoyo del Curso de Programación - Lenguaje C++ - Periodo (Feb - May) del año en curso
Parámetros por valor y por referencia de objetos
Parámetros por valor y por referencia de datos simples
Métodos constantes (const)
Parámetros de un método constante (const)
Definición de constantes (const)
Directiva #define
Puntero this
Métodos estáticos de una clase


« Estructuras dinámicas en C++: Listas genéricas doblemente en  |  Recursividad: Conceptos básicos »
 
Apps Infoudo
 
Buscador:
Powered by Google:


Web móvil
Imágenes
La Web

 

Síguenos por RSS


Puedes leerlos mediante el navegador Firefox, lectores de noticias en la computadora o el móvil o usando el servicio de Feedburner de Google para recibir las notificaciones por correo electrónico.
RSS - Suscribirse usando Feedburner de Google

email Recibir las nuevas publicaciones de Boludo por email

Atom


»Ir a URL
.....
Registra Gratis Tu Negocio
....
Sugerir un nuevo sitio WAP

...
¡Bloguea Ya!

..
Registro de Profesionales(Abogados, escritores, doctores, licenciados, ingenieros, etc.)
.
Soporte

Síguenos en las redes sociales

Síguenos en Facebook facebook.com/boludooficial Síguenos en Twitter @bolUDOoficial Síguenos en Instagram @boludooficial Síguenos en Telegram t.me/Boludooficial
Síguenos en WhatsApp BolUDOoficial Síguenos en YouTube youtube.com/@boludo.oficial
Síguenos en Facebook facebook.com/SergioAlemanFans Síguenos en Twitter @SergioAleman1 Síguenos en Instagram @sergioalemanfans
Síguenos en WhatsApp wa.me/qr/Y7Q232VLZPR5O1 Síguenos en Tiktok @sergioalemanoficial Síguenos en Tiktok @sergioalemanfans
Síguenos en Telegram t.me/SergioAlemanOficial Síguenos en YouTube youtube.com/@sergioaleman
Síguenos en Facebook facebook.com/INFOUDO.OFICIAL Síguenos en Twitter @infoudomon Síguenos en Instagram @infoudooficial Síguenos en Telegram t.me/Infoudooficial
Síguenos en Facebook facebook.com/tuinfou Síguenos en Twitter @infoudomonagas
Síguenos en WhatsApp INFO UDO Síguenos en YouTube youtube.com/@infoudooficial

Mis cuentas sociales

FB
Twitter
Pinterest
Instagram
Otras

Móvil: (0426 683 6955 - 0412 8226575) - E-mail: [email protected] - [email protected] - WhatsApp: +58 (0426) 683.69.55


Copyscape
Volver arriba

Protocolo  |  Mapa del Sitio  |  Report Abuse - DMCA  |  Términos y Condiciones  |  Ayuda  |  Privacidad de Datos  |  Política de Cookies  |  Reportar un bug  |  Licencia: CC BY-NC-ND 3.0

Copyright ©2023 Boludo. Todos los derechos reservados. Diseñado y Desarrollado por Sergio Alemán Mi perfil en GitHub


SUBIR