简体   繁体   中英

C doubly linked circular list insert

Doesn't insert and doesn't keep adresses of next and prev node: I'm trying to read input from file; It can read all data corectly and based on every line, creates an Aeronava object. It seems that the insert doesn't work.any suggestions?

void insertFAV_Av(FAVnode*list, Aeronava *av){
        FAVnode* nn = (FAVnode*)malloc(sizeof(FAVnode));
        //first = list;
        nn->infoUtil = (Aeronava*)malloc(sizeof(Aeronava));
        nn->infoUtil->idAeronava = (char*)malloc(strlen(av->idAeronava) + 1);
        //strcpy(nn->infoUtil->idAeronava, av->idAeronava);
        nn->infoUtil = av;
        if (first == NULL){
            nn->prev = nn->next = nn;
            first = nn;
        }
        else{
            list = first;
            while (list->next != first){
                list = list->next;
            }
            nn->prev = list;
            list->next = nn;
            nn->next = first;

        }
}


struct Aeronava{
    char* idAeronava;
    tipA tipAero;
    short int nrLocuri;
    double greutateMaxima;
};

struct FAVnode{
    FAVnode*next;
    FAVnode*prev;
    Aeronava* infoUtil;
};
        nn->prev = list;   // 1
        list->next = nn;   // 2
        nn->next = first;  // 3

Lines 1 and 2 link nn to list in both directions, but line 3 links nn with first in one direction only. You lack the opposite link update here:

        first->prev = nn;

I see a few problems here. First is this:

     else{
        list = first;
        while (list->next != first){
            list = list->next;
        }
        nn->prev = list;
        list->next = nn;
        nn->next = first;

You are assigning first to list. List is the passed parameter. By doing this, you are clobbering it. A proper insert routine looks like this:

void insert_node(node_t **head, node_t **tail, nodedata_t *data)
  {
    /* Do some stuff */


    /* Insert Node */
    if (*list == NULL)
        {
          *head = data;
          *tail = data;
      else
        {
          *tail->next = data;
          *tail->next->prev = *tail;
          *tail->next->next = NULL;
          *tail = data;
        }
  }

This inserts at the end of the list. For the middle of the list, you would change the code in the else to the following:

data->next = curr->next;
data->prev = curr;
data->next->prev = data;
curr->next = data;

The variable curr is being defined as "node_t *curr;" The way this works is that you have a pointer to data, and you have a pointer to the current node, and the node after current exists, which we call blue. So you set next in data to point to blue and prev in data to point to curr. Then you set prev in blue to point to data, and next in curr to point to data. Then the list insert is done. There is another special case that this didn't address, which is insertion at end of list. But I will leave that as an exercise for the reader.

One more thing I noticed. There is no need to typecast the pointer result from malloc. It's a void type which is compatible with all pointer types.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM