单链表的删除和逆置模块有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; 进行指针初始化。