有没有C语言高手帮我看看这个程序哪里出错了(构建线性链表,实现对其插入删除的操作)
#include<stdlib.h>
typedef struct LNode
{
int data;
struct LNode *next;
} LNode,*linklist;
//尾插法建立带表头节点的单链线性表
void createlist_l(linklist l,int n)
{
linklist q;
int i;
l=(linklist) malloc (sizeof(LNode));
l->next=0;
q=(linklist)malloc(sizeof(LNode));
printf("请输入结点的数据域\n");
for(i=n;i>0;i--)
{
scanf("%d",&q->data);
q->next=l->next;
l->next=q;
}
}
//在指定位置处插入一个节点
void listInsert_l(linklist l,int i,int e)
{
int j;
linklist p;
linklist q;
q=(linklist)malloc (sizeof(LNode));
p=(linklist)malloc (sizeof(LNode));
p=l;
j=1;
while(p&&j<i-1)
{
p=p->next;
++j;
}
if(j>i-1||!p)
printf("插入位置不合理");
else
{ q->data=e;
q->next=p->next;
p->next=q; }
printf("插入后的链表为:\n");
}
void listdelete_l(linklist l,int i)
{
linklist p;
linklist q;
int j;
q=(linklist)malloc(sizeof(LNode));
p=l;
for(j=1;j<i-1,!(p->next);j++)
p=p->next;
if(!p->next||j>i-1)
printf("删除位置不合理");
else
q=p->next;
printf("被删除的元素值是%d",q->data);
p->next=q->next;
free(q);
printf("删除后的链表为\n");
}
void print(linklist l)
{
linklist q;
q=l->next;
while(q!=0)
{
printf("%d,",q->data) ;
q=q->next;
}
}
void main ()
{
linklist l;
int n;
int k,e;
printf("请输入链表的元素个数\n");
scanf("%d",&n);
createlist_l(l, n);
printf("请输入所要插入的结点的位置及其数据域\n");
scanf("%d,%d",&k,&e);
listInsert_l(l, k,e);
print(l);
printf("请输入所要删除的结点的位置\n");
scanf("%d",&k);
listdelete_l(l, k);
print(l);
} 展开
下面是根据你的代码修改的,以后尽量不要用字母“l”(小写的L)作变量,容易跟数字1弄混,且不方便阅读。还有写的时候注意指针的用法,如果你要修改参数,就要用这个变量的指针,此处就为二级指针,因为要传送的形参已经是个指针了。
代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct LNode
{
int data;
struct LNode *next;
} LNode,*linklist;
//尾插法建立带表头节点的单链线性表,注意,第一个参数为指向链表指针的指针,是个二级指针
void createlist(linklist *head,int n)
{
linklist q=NULL,p=NULL; // p 指向表尾结点;q 指向动态分配的结点,即新建立的结点
int i; // 循环变量
for(i=n;i>0;i--)
{
q=(linklist)malloc(sizeof(LNode)); // 动态分配一个结点
printf("请输入结点的数据域:\n"); // 提醒输入数据
scanf("%d",&(q->data) ); // 输入结点的数据域
if(*head==NULL) // 链表为空时
{
*head=q; // 动态分配的结点地址赋给头结点
} // end if
else // 链表不为空时
{
p->next=q; // 把动态分配的结点地址赋给表尾的next指针
} // end else
p=q; // p 指向新的表尾结点
}
p->next = NULL; // 表尾结点的next赋值为空
}
// 链表打印函数。由于打印函数不修改链表,所以参数为指向链表的指针,是个一级指针
void print(linklist head)
{
if(head==NULL) // 空链表的情况
{
printf("The list is empty.\n");
return ;
} // end if
// 链表不为空时
linklist q; // 定义循环指针变量
q=head; // 把 头结点指针赋给 q
while(q!=0) // 直到链表结束,while才结束
{
printf("%d,",q->data); // 打印该结点的数据域
q=q->next; // q 指向下一个结点
} // end while
}
//在指定位置处插入一个节点
void listInsert(linklist *head,int i,int e)
{
int j; // 循环变量
linklist p;
linklist q;
q=(linklist)malloc(sizeof(LNode)); // 动态分配一个结点空间
if(i==1) // 在表头插入
{
q->next = *head;// 新分配的结点的链接成员 next 指向现在的头结点
q->data = e;
*head = q; // 把新分配的结点地址赋值给头结点指针
return ; // 函数结束
} // end if
// 不在表头插入的情况
p=*head;
j=1;
while( ((p->next)!=NULL)&&(j<i-1) ) // 在链表内,寻找插入位置
{
p=p->next;
++j;
} // end while
if(j<i-1) // 要插入的位置大于量表元素个数,即不合理
{
printf("插入位置不合理\n");
return ;
} // end if
else // 插入位置合理时
{
if(p->next==NULL) // 在表尾插入
{
p->next = q;
q->next = NULL;
q->data = e;
} // end if
else // 在表中间插入
{
q->next = p->next;
p->next = q;
q->data = e;
} // end else
} // end else
}
// 删除结点函数。第一个参数为一个二级指针,因为要修改链表。
void listdelete(linklist *head,int i)
{
if(*head==NULL) // 链表为空时
{
printf("The list is empty.NO DELETE!\n");
return ;
} // end if
// 链表非空时
linklist q=NULL;
if(i==1) // 删除的表头
{
q=*head;
*head = (*head)->next;
free(q);
return ;
} // end if
// 删除的不是表头的情况
linklist p=NULL;
int j;
// q=(linklist)malloc(sizeof(LNode));
p=*head;
for(j=1;(j<i-1)&&(p->next->next!=NULL);) // 循环结束后1)如果删除位置合理,j=i-1。另外,若要删除的是表尾元素,
// 则同时p->next=NULL 2) 若删除位置不合理,则j<i-1,此时,p->next为NULL
{
j++;
p=p->next;
} // end for
if(j<i-1) // 删除位置不合理
printf("删除位置不合理\n");
else // 要删除元素的位置合理
{
if(p->next==NULL) // 要删除的是表尾元素
{
q=p->next;
printf("被删除的元素值是%d.",q->data);
p->next=NULL; // 表尾的next元素置为空
free(q); // 释放要删除的元素内存
} // end if
else // 要删除的是表中间的元素
{
q=p->next;
p->next=q->next; // 以上两句为连接要删除元素的前后两个元素
printf("被删除的元素值是%d.\n",q->data); // 输出要删除的元素值
free(q); // 释放要删除元素占用的内存
} // end else
} // end else
}
// 主函数
void main ()
{
linklist head = NULL; // 定义链表指针
int n;
int k,e;
printf("请输入链表的元素个数\n");
scanf("%d",&n);
createlist(&head, n); // 调用建立链表元素
print(head); // 调用打印链表函数
printf("\n请输入所要插入的结点的位置及其数据域:\n");
scanf("%d%d",&k,&e);
listInsert(&head, k,e); // 调用插入元素函数
printf("\n"); // 打印换行,为了输出结果更简明
printf("插入后的链表为:\n");
print(head); // 调用打印链表函数
printf("\n请输入所要删除的结点的位置\n");
scanf("%d",&k);
listdelete(&head, k); // 调用删除元素函数
printf("\n删除后的链表为:\n");
print(head); // 调用打印链表函数
printf("\n");
return ; // 主函数结束
}
运行结果: