倒转列表的代码更简单,更快捷?

时间:2012-10-27 12:32:21

标签: c algorithm linked-list

我编写了用于反转每个节点中包含单词的双向链表的代码,这完全正常。 我的老师说这个算法很难理解,整个代码可以提高效率(减少开销和内存消耗)。我可以对代码/反转算法做出哪些更改? 还有一种方法我可以输入句子,而不必事先询问单词的数量?这是代码:

#include<stdio.h>
#include<conio.h>
#include<string.h>
typedef struct NODE
{
    char *item;
    struct NODE *next;
    struct NODE *prev;
}NODE;
void Insert(char data[],NODE **List)
{
    NODE *temp,*last;
    last=(*List);
    temp=(NODE*)malloc(sizeof(NODE));
    temp->item=(char*)malloc(strlen(data));
    temp->item=data;
    temp->next=NULL;
    temp->prev=NULL;
    if((*List)->item==NULL)
        (*List)=temp;
    else
    {
        while(last->next!=NULL)
            last=last->next;
        temp->prev=last;
        last->next=temp;
        last=temp;
    }
}
void Reverse(NODE **List)
{
    int flag1=0;
    NODE *temp,*temp1,*last,*flag;
    temp1=(NODE*)malloc(sizeof(NODE));
    last=(*List);
    while(last->next!=NULL)
        last=last->next;
    temp=last;
    while(temp->prev!=NULL)
    {
        temp1->item=temp->item;
        temp1->next=temp->next;
        temp1->prev=temp->prev;
        temp->next=temp->prev;
        temp->prev=temp1->next;
        temp=temp->next;
        if(flag1==0)
        {
            flag1++;
            flag=temp;
        }
    }
    temp1->item=temp->item;
    temp1->next=temp->next;
    temp1->prev=temp->prev;
    temp->next=NULL;
    temp->prev=temp1->next;
    (*List)=flag->prev;
    free(temp1);
};
void display(NODE *List)
{
    if(List->next==NULL)
    {
        printf("%s",List->item);
        return;
    }
    NODE *temp;
    temp=List;
    do
    {
        printf("%s<-->",temp->item);
        temp=temp->next;
    }while(temp->next!=NULL);
    printf("%s\n",temp->item);
}
int main()
{
    int i=0,n;
    char s[10][50];
    NODE *List;
    List=(NODE*)malloc(sizeof(NODE));
    List->item=NULL;
    List->next=NULL;
    List->prev=NULL;
    printf("Provide number of words(max 10): ");
    scanf("%d",&n);
    printf("Enter string of words for the list: ");
    while(i<n)
    {
        scanf("%s",s[i]);
        Insert(s[i],&List);
        i++;
    }
    printf("\nOriginal List is: ");
    display(List);
    Reverse(&List);
    printf("\nReversed List is: ");
    display(List);
    getch();
    return 0;
}

3 个答案:

答案 0 :(得分:5)

由于它是一个双链表,你可以编写两个遍历函数。一个前进,一个反向。在控件结构中为列表保存两个锚点:一个用于第一个元素,另一个用于最后一个元素。

答案 1 :(得分:3)

您可以为每个节点交换下一个和上一个指针,并交换尾部和头部指针。

答案 2 :(得分:1)

void reverse (struct node *ptr)
{
struct node *tmp, *kid;

if (!ptr) return;

for (kid = ptr->next; kid; kid = kid->prev) {
        tmp = kid->prev;
        kid->prev = kid->next;
        kid->next = tmp;
        }

for (kid = ptr->prev; kid; kid = kid->next) {
        tmp = kid->prev;
        kid->prev = kid->next;
        kid->next = tmp;
        }

tmp = ptr->prev;
ptr->prev = ptr->next;
ptr->next = tmp;

return;
}

注意:我删除了typedef。我讨厌typedef。