反转双向链表不会返回任何内容

时间:2018-04-22 17:01:31

标签: c doubly-linked-list

我试图在双向链表中反转元素,我似乎无法反转列表中的元素。它一直显示一个空白列表。在输入列表中的节点并将其打印出来之后,此功能应该反转列表中的节点,但在打印时它显示为空白。 (没有分段错误)

这是功能:

void reverse(List it) {
    Node *temp;
    Node *corr;
    temp = malloc(sizeof(Node));
    corr = malloc(sizeof(Node));

    corr = it->curr;

    while (corr != NULL) {
        temp = corr->prev;
        corr->prev = corr->next;
        corr->next = temp;  
        corr = corr->prev;
    }
}

3 个答案:

答案 0 :(得分:3)

您的代码中存在两个问题:

  • 无需分配新节点,实际上,当您将新值存储到corrtemp时,这些已分配的节点会丢失。

  • 您必须更新it->curr以指向反转列表的第一个节点,即原始列表的最后一个节点

以下是更正后的版本:

void reverse(List it) {
    Node *last = NULL;
    Node *corr = it->curr;

    while (corr != NULL) {
        Node *temp = corr->prev;
        corr->prev = corr->next;
        corr->next = temp; 
        last = corr; 
        corr = corr->prev;
    }
    it->curr = last;
}

另请注意,它被认为是错误的样式,并且容易在typedef后面隐藏指针。 List是指针的typedef,但是一个迷茫的读者可能首先相信你将值按结构传递给reverse函数......

答案 1 :(得分:1)

考虑到这一点后,我建议基于旧版本的以下新功能可能会起作用,但这有点猜测... - 关键更改是循环中的新行,请参阅下面的代码段

  while(corr!=NULL)
   {

     temp=corr->prev;
     corr->prev=corr->next;
     corr->next=temp;  
     it->curr=corr;  //this should make the last member the new first member
     corr=corr->prev;

    }

这有点不太优雅,因为it->corr会不断更改循环的每个循环,但是当它完成时it->corr应该有列表的第一个成员 - 这可能会使你的print语句工作,但正如我上面所说,这是一个猜测。

我删除了malloc,因为它不需要

工作版 - 下面测试的完整程序

#include <stdio.h>
#include <stdlib.h>

struct Node{
  struct Node * prev;
  struct Node * next;
  int ndata;
};

struct List {
  struct Node node[20];
  struct Node * curr;
};


void reverse(struct List *);
void printlist(struct List *);

int main()
{
  struct List it;

  int n;

  for (n=0;n<20;n++)  //set up a simple double linked list
    {
      it.node[n].ndata=n;
      if (n>1) 
    {
      it.node[n].prev=&(it.node[n-1]);
    }
      else
    {
      it.node[n].prev=NULL;
    }
      if (n<19) 
    {
      it.node[n].next=&(it.node[n+1]);
    }
      else
    {
      it.node[n].next=NULL;
    }
    }
  it.curr=&(it.node[0]);

  printlist(&it);
  reverse(&it);
  printlist(&it);
}

void printlist(struct List * it)
{

  struct Node *corr;

  corr = it->curr;

  while(corr!=NULL)
    {
      printf("%d\n",corr->ndata);
      corr=corr->next;
    }
  return;
}
void reverse(struct List * it)
{

  struct Node *temp;
  struct Node *corr;

  corr = it->curr;

  while(corr!=NULL)
    {
      temp=corr->prev;
      corr->prev=corr->next;
      corr->next=temp;  
      it->curr=corr;
      corr=corr->prev;
    }
  return;
}

输出在下面 - 注意我已经更改了节点和列表的格式,因为它们现在是在示例代码开头定义的结构

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0

(此版本没有内存泄漏。)

答案 2 :(得分:0)

我认为你不更新头指针,我不知道你的代码在哪里,所以我将在下面提供示例代码,其余的算法看起来还不错:

node* head = 0;

void rotate(node** h) {
    node *curr = *h, *tmp = 0;

    while (curr) {
        node* tmp = curr->prev;
        curr->prev = curr->next;
        curr->next = tmp;
        if (!tmp) {
            break;
        }
        curr = tmp;
    }
    //Update head!
    *h = curr;
}

void print(node* head) {
    while (head) {
        printf("%d", head->v);
        head = head->next;
    }
}