单链表的删除和逆置模块

单链表的删除和逆置模块有bug,求指明。

#include"stdio.h"
#include
#define ERROR 0
#define OK 1
typedef int ElemType;  

typedef struct Node//结点类型定义 
{
    ElemType data;
    struct Node * next;
}Node, * LinkList;//LinkList为结构指针类型 

InitList (LinkList * L)//初始化单链表  
{
    *L=(LinkList)malloc(sizeof(Node));//建立头结点 
    (*L)->next=NULL;//建立空的单链表L 
} 

void CreateFromHead(LinkList L)//头插法逆序建表 
{
        Node * s;
        int c;
        int flag=1;
        while(flag)//flag初值为1,当输入9999时,置flag为0,建表结束
        {
            scanf("%d",&c);
            if(c!=9999)
                {
                    s=(Node*)malloc(sizeof(Node));//建立新结点S 
                    s->data=c;
                    s->next=L->next;//将S结点插入头结点 
                    L->next=s;
                }
            else flag=0;
        } 
} 

void CreateFromTail(LinkList L)//尾插法顺序建表
{
    int c;
    Node * r,* s;
    int flag=1;
    r=L;//r指针动态指向链表的当前表尾,以便于插入表尾,其初值指向头结点 
    while(flag)
    {
        scanf("%d",&c);
        if(c!=9999)
            {
                s=(Node*)malloc(sizeof(Node));
                s->data=c;
                r->next=s;
                r=s;    
            }
        else
            {
                flag=0;
                r->next=NULL;//将最后一个结点的next链域置为空,表示链表的结束 
            }    
    }
}

Node * Get(LinkList L,int i)//按序号查找 
{
    int j;
    Node * p;
    p=L->next;
    if(i<=0) return NULL;
    p=L;j=0;//从头结点开始扫描 
    while((p->next!=NULL)&&(jp=p->next;//扫描下一个结点 
        j++;//结点计数器 
    }
    if(i==j)//找到了第i个结点
    {    
        printf("该结点为%d\n",p->data); 
        return p;
    } 
    else printf("未找到该结点\n"); return p;//找不到,,i<=0或i>n 
}

Node * Locate(LinkList L,ElemType key)//按值查找
{
    int i;
    Node * p;
    p=L->next;
    while(p!=NULL)//当前表未查完 
    {
        if(p->data!=key)
            {
                p=p->next;
            }
        else//找到结点值=key时退出循环
            {
                printf("该值存在\n");
                break; 
            }      
    }
    return p;
}

int ListLength(LinkList L)//求单链表的长度 
{
    int j;
    Node * p;
    p=L->next;
    j=0;
    while(p!=NULL)
    {
        p=p->next;
        j++;    
    }
    printf("%d",j);
    printf("\n");        
}

int InsList(LinkList L,int i,ElemType e)//单链表插入操作 
{
    Node * pre,* s;
    int k;
    if(i<=0) return ERROR;
    pre=L;k=0;//从头结点开始,查找第i-1个结点 
    while(pre!=NULL&&k1)//表未查完且未查到第i-1个时重复,找到pre指向第i-1个 
    {
        pre=pre->next;
        k=k+1;
    }
    if(pre==NULL)//pre为空,表已找完,但是未数到i-1个,说明插入位置不合理 
    {
        printf("插入位置不合理!");
        return ERROR;
    }
    s=(Node *)malloc(sizeof(Node));//申请新节点s 
    s->data=e;//值e置入s的数据域 
    s->next=pre->next;//修改指针,完成插入操作 
    pre->next=s;
    return OK;
}

int DelList(LinkList L,int i,ElemType *e)//单链表的删除操作 
{
    Node * pre,* r;
    int k;
    pre=L;k=0;
    while(pre->next!=NULL&&k1)//寻找被删除结点i的前驱i-1使p指向它 
    {
        pre=pre->next;
        k=k+1;
    }
    if(pre->next==NULL)//没有找到合法的前驱位置 
    {
        printf("删除结点的位置i不合理!");
        return ERROR; 
    }
    r=pre->next;
    pre->next=r->next;//修改指针,删除结点r 
    *e=r->data;
    free(r);//释放被删除的结点所占的内存空间 
    return OK;
}

Node* MergeLinkList(LinkList LA, LinkList LB)//将单链表链接到另一个单链表的末尾 
{
 Node * pa, *pb;
 pa = LA->next;
 pb = LB->next;
 int i,n;
 n = ListLength(LA);
 for ( i = 1; i < n; i++)
 {
  pa = pa->next;
 }
 pa->next = pb;
}


void ListPrint(LinkList L){//输出单链表各元素 
    Node* p = L->next;
    while (p != NULL)
    {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

void BubbleSort(Node * L)
{
    int i ,count = 0, num;
    Node *p, *q, *tail;
    p = L;
    while(p->next != NULL)
    {
        count++;
        p = p->next;
    }
    for(i = 0; i < count - 1; i++)
    {
        num = count - i - 1;
        q = L->next;
        p = q->next;
        tail = L;
        while(num--)
        {
            if(q->data > p->data)
            {
                q->next = p->next;
                p->next = q;
                tail->next = p;
            }
            tail = tail->next;
            q = tail->next;
            p = q->next;
         } 
    } 
}

Node* ReverseList(LinkList L)//目前尚有bug 
{
    Node *head;
    Node *temp=NULL,*Phead=NULL; 
    while(head!=NULL)
    {
        temp=head;
        head=head->next;
        temp->next=Phead;
        Phead=temp;
    }
    return Phead; 
 } 

int main()
{
    LinkList L1,L2;
    InitList(&L1);InitList(&L2);
    int choose,n,n1,n2,i,j,key;
    int *e;
    for(i=0;i<11;i++)
    {
        printf("*********************************************\n");
        printf("*                    菜单                   *\n");
        printf("*    1:头插逆序建表       2:尾插顺序建表    *\n"); 
        printf("*    3:单链表插入         4:单链表删除      *\n");
        printf("*    5:按序号查找         6:按值查找        *\n");
        printf("*    7:求单链表长         8:单链表排序      *\n");
        printf("*    9:单链表逆置         10:合并有序链表   *\n");
        printf("*********************************************\n");
        printf("输入想要进行操作的序号:"); 
        scanf("%d",&choose);
        
        if(choose==1)//头插逆序建表 
        {
            printf("头插法逆序建表L1(输入9999结束):\n");
            CreateFromHead(L1);
            printf("当前单链表L1各元素为:");
            ListPrint(L1);
            printf("头插法逆序建表L2(输入9999结束):\n");
            CreateFromHead(L2);
            printf("当前单链表L2各元素为:");
            ListPrint(L2);
        }
        if(choose==2)//尾插顺序建表 
        {
            printf("尾插法逆序建表L1(输入9999结束):\n");
            CreateFromTail(L1);
            printf("当前单链表L1各元素为:");
            ListPrint(L1);
            printf("尾插法逆序建表L2(输入9999结束):\n");
            CreateFromTail(L2);
            printf("当前单链表L2各元素为:");
            ListPrint(L2);    
        }
        if(choose==3)//单链表插入 
        {
            printf("L1表:\n");
            printf("请输入插入元素的个数:");
            scanf("%d",&n1);
            for(j=1;j<=n1;j++)
            {
                printf("请输入要插入元素的位置:");
                scanf("%d",&i);
                printf("请输入要插入的元素:");
                scanf("%d",&n);
                InsList(L1,i,n);
            }
            printf("当前L1表各元素为:");
            ListPrint(L1);
            printf("L2表:\n");
            printf("请输入插入元素的个数:");
            scanf("%d",&n2);
            for(j=1;j<=n2;j++)
            {
                printf("请输入要插入元素的位置:");
                scanf("%d",&i);
                printf("请输入要插入的元素:");
                scanf("%d",&n);
                InsList(L2,i,n);
            }
            printf("当前L2表各元素为:");
            ListPrint(L2);
        } 
        if(choose==4)//单链表删除 目前有bug 
        {
            printf("L1表:\n");
            printf("请输入删除元素的个数:");
            scanf("%d",&n1);
            for(j=1;j<=n1;j++)
            {
                printf("请输入要删除元素的位置:");
                scanf("%d",&i);
                DelList(L1,i,e);
            }
            printf("当前L1表各元素为:");
            ListPrint(L1);
            printf("L2表:\n");
            printf("请输入删除元素的个数:");
            scanf("%d",&n2);
            for(j=1;j<=n2;j++)
            {
                printf("请输入要删除元素的位置:");
                scanf("%d",&i);
                DelList(L2,i,e);
            }
            printf("当前L2表各元素为:");
            ListPrint(L2);    
        }
        if(choose==5)//按序号查找 
        {
            printf("L1表为:");
            ListPrint(L1);
            printf("L2表为:");
            ListPrint(L2);
            printf("在L1表中查找第i个结点:");
            scanf("%d",&i);
            Get(L1,i);
            printf("在L2表中查找第i个结点:");
            scanf("%d",&i);
            Get(L2,i);        
        }
        if(choose==6)//按值查找 
        {
            printf("L1表为:");
            ListPrint(L1);
            printf("L2表为:");
            ListPrint(L2);
            printf("请输入要在L1表中查找的值:");
            scanf("%d",&key);
            Locate(L1,key);
            printf("请输入要在L2表中查找的值:");
            scanf("%d",&key);
            Locate(L2,key);
        }
        if(choose==7)//求单链表长 
        {
            printf("L1表为:");
            ListPrint(L1);
            printf("L2表为:");
            ListPrint(L2);
            printf("L1表的表长为:");
            ListLength(L1);
            printf("L2表的表长为:");
            ListLength(L2);
        }
        if(choose==8)//单链表排序 
        {
            printf("排序前L1表为:");
            ListPrint(L1);
            printf("排序前L2表为:");
            ListPrint(L2);
            printf("排序后L1表为:");
            BubbleSort(L1);
            ListPrint(L1);
            printf("排序后L2表为:");
            BubbleSort(L2);
            ListPrint(L2);
        }
        if(choose==9)//单链表逆置 目前有bug 
        {
            printf("逆置前L1表为:");
            ListPrint(L1);
            printf("逆置前L2表为:");
            ListPrint(L2);
            printf("逆置后L1表为:");
            ReverseList(L1);
            printf("逆置后L2表为:");
            ReverseList(L2);
        }
        if(choose==10)//合并有序链表 
        {
            printf("合并前L1表为:");
            ListPrint(L1);
            printf("合并前L2表为:");
            ListPrint(L2);
            MergeLinkList(L1,L2);
            printf("合并后的新表为:");
            BubbleSort(L1);
            ListPrint(L1);
        } 
    }
    
}

参考GPT和自己的思路:

在逆置链表函数ReverseList中,头结点指针head没有进行初始化,直接使用会出现未定义行为,导致程序异常。应该在函数开头添加初始化语句:head = L->next。同时,在函数最后应该返回逆置后的头结点Phead而不是原来的L。

另外,在单链表删除函数DelList中,指针变量e应该是一个指向ElemType类型的指针,即int* e,但是代码中没有进行指针的初始化,可能导致程序异常。在函数调用前应该添加int* e = NULL; 进行指针初始化。