1

リスト内の任意の場所で要素を挿入および削除できる c を使用して、単純なリンクされたリストを作成しました。次のコードを使用して最初のノードを削除しようとするまで、コードは正常に機能しました。

typedef struct l_list
{
    int data,index;
    struct l_list *next_node;
}node;
static int total_node=0;
node *search(node *,int,node **);

int main()
{
int choice,key;
char ans;
node *new_node,*head, *p_node,*index_change,*cur;
node *get_node();
head=NULL;


printf("Program for Linked List.\n");
do
{
    printf("\n1. Create Node");
    printf("\n2. Delete Node");
    printf("\n3. Traverse the List");
    printf("\n4. Exit");
    printf("\nEnter your choice: ");
    scanf("%d",&choice);

    switch(choice)
    {
        case 1:
            do
            {
                total_node++;
                new_node=get_node();
                printf("\nEnter the data you want to insert: ");
                scanf("%d",&new_node->data);

                if(head==NULL)
                {
                    head=new_node;
                    head->index=1;
                }
                else
                {
                printf("\nWhich node you want to insert it as:\n");
                for(int i=1;i<=total_node;i++)
                {
                    printf("%d ",i);
                }
                printf("==) ");
                scanf("%d",&key);
                //printf("\b\b-|-");
                if(key==1)
                {
                    new_node->next_node=head;
                    head=new_node;
                }
                else
                {
                    p_node=search(head,key,&cur);
                    new_node->next_node=p_node->next_node;
                    p_node->next_node=new_node;
                //p_node=NULL;
                }
                new_node->index=key;
                index_change=new_node->next_node;
                while(index_change!=NULL)
                {
                    index_change->index=++key;
                    index_change=index_change->next_node;
                }

                }

                printf("\nDo you want to insert more node in the linked list: [y/n]");
                //ans=getch();
            }while((ans=getch())=='y');

            break;

//Deletion code.
case 2:
            do
            {
                if(head==NULL)//head is first node of the list
                {
                    printf("\nUNDERFLOW!\nThe linked list is already empty.\n");
                }
                else
                {
                    printf("Which node you want to delete:\n");
                    for(inti=1;i<=total_node;i++)
                        printf("%d ",i);  //total_node=variable taken
                    printf("==) ");      //to track the total no of node
                    scanf("%d",&key); //key=node index to be deleted
                    //printf("\b\b-|-");
                    if(key==1)
                    {
        //If we need to delete the first node when only one node is left                
                            if(total_node==1)
                            {
                            //p_node=head;
                            head=NULL;

                            }
                //If we need to delete the first node when more than one node are there
                        else
                            {
                            //p_node=head;
                            head=head->next_node;
                            }
                        total_node--;
                    }
                    else
                    {
                        p_node=search(head,key,&cur);//returns node just before the node to be deleted
                        p_node->next_node=cur->next_node;//cur gets the value of the node that is to be deleted.
                        total_node--;
                    }
                    index_change=p_node->next_node;
                    while(index_change!=NULL)//to change the index of following nodes.
                    {
                        index_change->index=key++;
                        index_change=index_change->next_node;
                    }
                }
                printf("\nDo you want to delete more nodes: [y/n]\n");
            }while((ans=getch())=='y');
case 3:
        if(head==NULL)
            printf("\nThe linked list is empty.\n");
        else
        {
            printf("\nThe elements of linked lists are as follows:\n\n");
            p_node=head;
            while(p_node!=NULL)
            {
                printf("[%d]->%d  ",p_node->index,p_node->data);
                p_node=p_node->next_node;
            }
        }
        break;


    }
}while(choice!=4);



return 0;
}

    node *get_node()
    {
        node *temp1;
        temp1= new node;
        temp1->next_node=NULL;
        return temp1;
    }

    node *search(node *head,int key,node **cur)
    {
        node *current,*prev;
        current=head;
        while(current!=NULL)
        {                
            if(current->index==key)
            {
                return prev;
            }
            prev=current;
            current=current->next_node;
            *cur=current;
        }
        return prev;
    }

プログラムがクラッシュする最初のノードを削除しようとすると、このコードを使用します。そして、次のような一時変数を使用すると

if(key==1)
                    {
                        if(total_node==1)
                            {
                            p_node=head;
                            head=NULL;
                            }
                        else
                            {
                            p_node=head;
                            head=p_node->next_node;
                            }
                        total_node--;
                    }

プログラムは正常に動作します。だから私が聞きたいのは、ヘッドノードを直接削除できるか、またはヘッドノードを削除するために常に別の一時構造ポインターが必要かということです。

4

3 に答える 3

2

この行で:

index_change=p_node->next_node;

あなたは逆参照しp_nodeます。ただし、最初のノードを削除する場合は、 の値を設定しませんp_node。観察されたクラッシュはp_node、有効なメモリ アドレスを保持していないことが原因である可能性があります。

于 2013-10-08T06:58:02.670 に答える
1

発生している正確なエラーと完全なプログラムがなければ、何が起こっているのかを言うのは困難です。

すぐに間違っているように見えることの 1 つは、データを含むノード (自分の) を割り当てることです。struct Linked_Listこれは、リンクされたリストで必要なことではありません。リンクされたリストでは、ポインターを変更したいだけで、データのコピーを防ぎます。

また、プログラムの構造が非常に悪いです。特定の操作を別の関数に移動することを検討し、これらのそれぞれについてテストを記述します。これにより、簡潔で完全なコード サンプルを質問と共に投稿することもできます。

エラーに近づくには、デバッガーを使用するか、何が起こっているかを示す print ステートメントをコードに追加します。

于 2013-10-08T07:18:19.560 に答える
0

この行で:

p_node=search(head,key,&cur);//returns node just before the node to be deleted

最初のノードを削除しようとすると、 headすでに設定されているポインターを渡します。NULL

headしたがって、リンクリストの先頭に到達する他の方法がないため、コードが実行する必要がある関数内のポインターを逆参照することはできませんsearch(私が信じているように)。

于 2013-10-08T07:03:53.930 に答える