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

これは二重にリンクされたリストなので、2 つのトラバーサル関数を書くだけで済みます。順方向に 1 つ、逆方向に 1 つ。リストの 2 つのアンカーを制御構造に保存します。1 つは最初の要素用で、もう 1 つは最後の要素用です。

于 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 に答える