简体   繁体   中英

I'm making a linked list that has to swap it's order

I'm writing a program that uses a doubly linked list. first, it takes 2 numbers from the input. the second number is to be used later but the first number, n, is used in a function to arrange the linked list so that it goes from n to 1 like n->n-1->n-2->...->1 while using next or prev to move between nodes. Then another function takes the same linked list and swaps it around so it goes from 1 to 'n' but I can't figure out how to get it to swap. Everything I change or try either shows up as a segmentation fault or returns the same list without changing anything. Also, this is my first time having to use this website for any issues I have with coding so if I am doing something wrong, kindly let me know so I can avoid making any mistakes

This is for a homework assignment in my computer science 1 class that is due 10/25/2019. I just need help on the part of the code that is giving me the issues I cannot fix.

typedef struct nod{
  int data;
  struct nod *next;
  struct nod *prev;
}soldier;
soldier *head = NULL;


soldier* create_soldier (int sequence);
soldier* create_reverse_circle(int n);
soldier* rearrange_circle(soldier *head);
void display(soldier *head);
int kill(soldier* head, int n, int k);

//dynamically allocates a solider node
soldier* create_soldier (int sequence){
  soldier *temp = (soldier *)malloc(sizeof(soldier));
  temp->data = sequence;
  temp->next = NULL;
  temp->prev = NULL;
  return temp;
}

//creates a list of soliders from n to 1
soldier* create_reverse_circle(int n){
  soldier *temp = NULL;
  soldier *t = NULL;
  int i;
  //printf("w");
  for(i = n; i > 0; i--){
    temp = create_soldier(i);

    if(head==NULL){
      head=temp;
      temp->next=head;
    }
    else{
      t=head;
      t->prev = t;
      while(t->next!=head){
        t=t->next;
      }
      t->next=temp;
      temp->prev = t;
      temp->next=head;
    }
  }

  return head;
}

 //rearranges the soliders in the list to go from 1 to n
 //the function I am having issues with
soldier* rearrange_circle(soldier* head){
  soldier *t = (soldier *)malloc(sizeof(soldier));
  soldier *temp = NULL;
  soldier *exc = head;
  int h = 0;
  int k = 1;

  //printf("\ntest 1:");  for test purposes
  while(exc != head){
    //tamp->data = k;
    temp = exc;
    temp->next = exc->prev;
    temp->prev = exc->next;

    if(h != 1){
      head = temp;
      temp->next = head;
      h = 1;
    }
    else{

      t = head;
      while(t->next != head)
        t=t->next;
      t->next = temp;
      temp->prev = t;
      head->next = t->next;
      temp->next = head;
    }

    exc = exc->next;
    temp = temp->next;
    //k++;
  }

  //printf("h = %d\n", h); also for test purposes


  return head;
}

//displays the head of the list
 void display(soldier* head){
  soldier *temp=head;
  while(temp->next != head){
    printf("%d->", temp->data);
    temp = temp->next;
  }
  printf("%d", temp->data);

}

The user is suppose to input 2 numbers. the first number, n, determines the loop and the second number, k, will be used later. the first function, create_reverse_circle, should take n and return a doubly linked list going from n to 1 to the main function to get printed in the display function. Then, another function, rearrange_circle, takes that linked list, reverses the order so it goes from 1 to n, and returns it to main function to get printed again in the display function (which only prints the same result it did the first time, given that there isn't a segmentation fault). Once the list has been swapped, an int function that I've left out because I have it solved, should use the linked list, N and the second number, K, to remove all the other nodes in the function until k+1 is remaining and return that value to be printed in the main.

Based on this , you can reverse the list this way:

/* Function to reverse a Doubly Linked List */
void reverse(soldier **head_ref)  
{  
    soldier *temp = NULL;  
    soldier *current = *head_ref;  

    /* swap next and prev for all nodes of  
    doubly linked list */
    while (current != NULL)  
    {  
        temp = current->prev;  
        current->prev = current->next;  
        current->next = temp;              
        current = current->prev;  
    }  

    /* Before changing the head, check for the cases like empty  
        list and list with only one node */
    if(temp != NULL )  
        *head_ref = temp->prev;  
} 

Note that it does not make a new list which is reversed, instead it destructively takes the list and reverses it, also to do this you need to pass it a pointer to a "pointer to the head", and then you can reach the result in the "pointer to the head" (must be the same thing you passed the pointer of). If however you would like to keep the original list in one piece, you can copy the whole list first, then reverse that new list. Code for copying list, based on this :

soldier *copy(soldier *start1)
{
    if(start1==NULL) return;
    soldier *temp=(soldier *) malloc(sizeof(soldier));
    temp->prev=start1->prev;
    temp->data=start1->data;
    temp->next=copy(start1->next);
    return temp;
}

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