How to order with insert sort a linked list c ++

2

I have a program in c ++ in which I want to manage the sorting method InsertSort .

I request the data with a case in the main.cpp file and then in the file List.cpp I can indicate where to insert it, in this case I have the insertInit.

case 1:
        cout << "Codigo: ";
        cin >> codigoDistribuidora;
        nuevo.guardaNombre(codigoDistribuidora);
        cout << "Nombre: ";
        cin.ignore();
        getline(cin, nombreDistribuidora);
        nuevo.guardaNombre(nombreDistribuidora);
        cout << "Domicilio: ";
        getline(cin, domicilioDistribuidora);
        nuevo.guardaNombre(domicilioDistribuidora);
        cout << "Telefono: ";
        cin >> telefonoDistribuidora;
        nuevo.guardaNombre(telefonoDistribuidora);
        cout << "Nombre del gerente: ";
        cin.ignore();
        getline(cin, nombreGerente);
        nuevo.guardaNombre(nombreGerente);
        l.insertaInicio(nuevo);
        break;

and the start insert is this:

void Lista::insertaInicio(Distribuidora dato) {
Nodo *tmp = new Nodo;
Nodo *aux = inicio;
tmp->guardaObjeto(dato);

tmp->guardaNodoSig(NULL);

bool nada = vacia();
if (nada) {
    inicio = tmp;
}
else {
    tmp->sig = aux;
    inicio = tmp;
}
string nombreDistribuidora = dato.damenombreDistribuidora();
string codigoDistribuidora = dato.damecodigoDistribuidora();
cout << "Has agregado la Distruibuidora con el nombre: '" << nombreDistribuidora << "' y codigo '" << codigoDistribuidora << "'" << endl;
}

As it would be a way to use InsertSort and order them when you insert them. I hope you understand me thank you.

    
asked by Eduardo Javier Maldonado 04.04.2016 в 07:41
source

2 answers

2
case 1:
    cout << "Codigo: ";
    cin >> codigoDistribuidora;
    nuevo.guardaNombre(codigoDistribuidora);
    cout << "Nombre: ";
    cin.ignore();
    getline(cin, nombreDistribuidora);
    nuevo.guardaNombre(nombreDistribuidora);
    cout << "Domicilio: ";
    getline(cin, domicilioDistribuidora);
    nuevo.guardaNombre(domicilioDistribuidora);
    cout << "Telefono: ";
    cin >> telefonoDistribuidora;
    nuevo.guardaNombre(telefonoDistribuidora);
    cout << "Nombre del gerente: ";
    cin.ignore();
    getline(cin, nombreGerente);
    nuevo.guardaNombre(nombreGerente);
    l.insertaInicio(nuevo);
    break;

The previous code should go in a separate function. Apart from greatly improving the readability of the code, it must be borne in mind that the switch sentences can be quite dangerous if a break disappears or if the code sneaks prematurely. It is highly recommended to have case as simple as possible.

On the other hand, and given that you do not include the full implementation of Lista , I mention that in the insertaInicio function you can have a problem:

void Lista::insertaInicio(Distribuidora dato) {
  Nodo *tmp = new Nodo;
  Nodo *aux = inicio; // <<--- AQUI!!!
}

What happens if the list is empty and, as a result, inicio points to nullptr ? Since you are making a copy of inicio in aux it is not valid to modify the address pointed to by aux , since in that case inicio will not find out.

Well, speaking of your problem, what you have to do is find at what point of the list you have to insert the new element. In this way the list will ALWAYS be ordered. What you need is to determine the way to sort the list:

  • By distributor code?
  • By name of distributor?
  • By the phone number?

If we assume that you choose the first option the algorithm and that the order is increasing, to determine the position of the new element would be the following:

  • If inicio is nullptr the list is empty, then inicio points to the new element and we have finished
  • Otherwise, go through the elements of the list until you find a code that is greater than that of the element to be added. The new element will have to be inserted between that node and the previous one.
  • Said with a code could be something like this:

    Nodo* nuevo = new Nodo;
    // falta la inicialización del nodo
    
    if( inicio == nullptr )
      inicio = nuevo;
    else
    {
      Nodo* previo = inicio;
    
      Nodo* siguiente = inicio->sig;
    
      while ( siguiente != nullptr && siguiente->damecodigoDistribuidora() < nuevo->damecodigoDistribuidora() )
      {
        previo = siguiente;
        siguiente = previo->sig;
      }
    
      // Podemos llegar a este punto desde dos caminos diferentes
      // 1. El código de siguiente es mayor que el del nuevo elemento
      // 2. Hemos llegado al final de la lista
      // En cualquier caso la operativa es exactamente la misma:
      // Insertar el nodo entre previo y siguiente
      previo->sig = nodo;
      nodo->sig = siguiente;
    }
    

    Greetings.

        
    answered by 04.04.2016 / 10:24
    source
    1

    Apparently you are working with a list just linked which makes the insertion process orderly slightly more complicated.

    In this type of list, the ordered insertion process is divided into:

  • Locate the insertion point : traverse the nodes from your root to the last node (top) by comparing the input value with the stored one; At the moment when the entry value is lower than the one stored (or you have reached the top) you will have found the insertion point.
  • Create the new node : you must link it to the node of the insertion point (the first one that contains a value greater than the input or the top).
  • Re-link the nodes : the node before the insertion point must point to the newly created node.
  • Nodo *anterior = inicio;
    Nodo *punto_insercion = anterior->sig;
    
    while (punto_insercion  && (punto_insercion->dato > dato))
    {
        anterior = punto_insercion;
        punto_insercion = punto_insercion->sig;
    }
    
    // Una vez superado el bucle, punto_insercion apunta
    // al nodo inmediatamente superior al actual o al tope
    
    anterior->sig = new Nodo(dato, punto_insercion);
    

    In the example code above I am assuming:

    • The list is not empty.
    • Nodo has a constructor that receives dato and the node to point to.
    • The dato to compare has a greater operator-than > .

    Keep in mind that what I have written is a guide, you must adapt it to your needs and keep in mind that I have not tried the pseudo-code

        
    answered by 04.04.2016 в 10:09