c - 我正在制作一个必须交换其顺序的链表

标签 c linked-list doubly-linked-list

我正在编写一个使用双向链表的程序。首先,它从输入中获取 2 个数字。第二个数字稍后使用,但第一个数字 n 在函数中用于排列链表,使其从 n 到 1,如 n->n-1->n-2->... ->1 同时使用 next 或 prev 在节点之间移动。然后另一个函数采用相同的链表并将其交换,因此它从 1 变为 'n' 但我不知道如何让它交换。我更改或尝试的所有内容要么显示为段错误,要么返回相同的列表而不更改任何内容。另外,这是我第一次不得不使用这个网站来解决我在编码方面遇到的任何问题,所以如果我做错了什么,请告诉我,这样我就可以避免犯任何错误

这是我的计算机科学 1 课的作业,该作业将于 2019 年 10 月 25 日到期。我只需要有关给我无法解决的问题的代码部分的帮助。

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);

}

假设用户输入 2 个数字。第一个数字 n 决定循环,第二个数字 k 稍后将使用。第一个函数 create_reverse_circle 应该接受 n 并返回一个从 n 到 1 的双向链表到主函数,以便在显示函数中打印。然后,另一个函数 rearrange_circle 获取该链表,反转顺序,使其从 1 变为 n,并将其返回给 main 函数,以便在 display 函数中再次打印(它只打印与第一次相同的结果,假设没有段错误)。交换列表后,我遗漏了一个 int 函数,因为我已经解决了它,应该使用链表 N 和第二个数字 K 来删除函数中的所有其他节点,直到 k+1 是剩余并返回要在 main 中打印的值。

最佳答案

基于 this ,你可以这样反转列表:

/* 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;  
} 

请注意,它不会创建一个颠倒的新列表,而是破坏性地获取列表并将其颠倒,为此,您需要向它传递一个指向“指向头部的指针”的指针,然后您可以在“指向头部的指针”中达到结果(必须与您传递指针的指针相同)。 但是,如果您想将原始列表保留在一个片段中,您可以先复制整个列表,然后反转新列表。 复制列表的代码,基于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;
}

关于c - 我正在制作一个必须交换其顺序的链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58531869/

相关文章:

c - 内核:检查进程是否在 c 中运行的正确方法

c - 对 sqlite_open 的 undefined reference

pointers - 解码嵌套结构和类型断言

c - 为什么我的循环会创建额外的链表节点?

java - 理解链表

c - 使用 L-System 优化 GNU 解析器

C中输入的字符计数

java - LinkedList addLast 函数替换列表中的其他值

C - 双向链表始终为空

java - 我收到两个 NullPointerExceptions,我不确定如何解决