1

我编写了用于反转包含每个节点中的单词的双向链表的代码,它工作得非常好。我的老师说该算法很难理解,并且可以使整个代码更高效(减少开销和内存消耗)。我可以对代码/逆向算法进行哪些更改?还有没有一种方法可以输入句子而不必提前询问单词的数量?这是代码:

#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;
}
4

3 回答 3

5

因为它是一个双链表,你可以只写两个遍历函数。一正一反。在控制结构中为列表保存两个锚点:一个用于第一个元素,一个用于最后一个元素。

于 2012-10-27T12:39:47.177 回答
3

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

于 2012-10-27T12:39:22.650 回答
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。

于 2012-10-27T13:18:31.553 回答