C语言 链表插入, 删除, 查询问题
假如,现在存在这样一个数组,链表的 具体 操作 , 例如 :
建立一个函数Insert( i , x) ,(在 i 位置插入 x 这个 元素)
Delete(i) , Delete(x) [ 删除元素为 x 的 所有索引 ) ,
查询Serch( List , x) (是否 存在 x , 获取 其 所在 下 标) ;
追问:需要 那么 复杂 吗??
假如,现在存在这样一个数组,链表的 具体 操作 , 例如 :
建立一个函数Insert( i , x) ,(在 i 位置插入 x 这个 元素)
Delete(i) , Delete(x) [ 删除元素为 x 的 所有索引 ) ,
查询Serch( List , x) (是否 存在 x , 获取 其 所在 下 标) ;
追问:需要 那么 复杂 吗??
答案:#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#define M 2/*总共有多少科*/
#define NULL 0
struct student/*定义一个结构体*/
{
long number;/*一个学生的学号*/
char name[25];/*姓名*/
float score[M];/*各科成绩*/
float sum;
float average;
struct student *next;/*存储下一个节点的地址*/
};
int n=0; /*全局变量,节点的个数*/
struct student*creat(void);/*创建一个链表*/
void print(struct student * head);/*函数功能:输出链表的内容,同时输出每个学生的总分和平均分*/
struct student *xiugai(struct student * head);/*函数功能:修改指定的某个学生的信息*/
struct student *del(struct student *head,long num);/*函数功能:删除某一节点*/
struct student *insert(struct student *head,struct student *stu,int i);/*函数功能:添加某一节点*/
struct student *searchnode(struct student *head,long num);/*函数功能:查找指定学号的结点的地址*/
void SUM(struct student *p);/*函数功能:求一个学生总分(一个结点p的zongfen)*/
void DeleteMemory(struct student *head);/*函数功能:释放head指向的链表中所有节点占用的内存*/
void main()
{
struct student *head=NULL,*stu;
long dele_num,number;
char c;
int l,i,position;
printf("您必须要创建链表,最后输出链表(链表在最后要手动释放)\n");
head=creat();
//在这里加一个循环的函数调用,求每一个节点的sum和average等。(应该再定义一个函数,求一个节点的sum average)
//输出刚创建的链表
do
{
printf("*****************请输入您的选项*****************\n");
printf("1.增加一个学生的信息\n");
printf("2.修改一个学生的信息\n");
printf("3.删除一个学生的信息\n");
printf("4.查看某一个学生的信息\n");
printf("5.结束程序\n");
printf("************************************************\n");
scanf("%d",&l);
switch(l)
{
case 1:printf("please input position:");
scanf("%ld",&position);
stu=(struct student*)malloc(sizeof(struct student));
printf("plaese input the student's number\n");
scanf("%ld",&stu->number);/*输入该生的学号*/
printf("plaese input the student's name\n");
scanf("%s",stu->name);getchar();/*输入名字*/
for(i=0;i<M;i++)
{
printf("please input the student's score\n");
scanf("%f",stu->score+i);getchar();/*输入分数*/
}
stu->next=NULL;
head=insert(head,stu,position);
print(head);break;
case 2:head=xiugai(head);
print(head);break;
case 3:printf("please input dele_num:");
scanf("%ld",&dele_num);
getchar();
head=del(head,dele_num);
print(head);break;
case 4:printf("please input num:");
scanf("%ld",&number);
getchar();
head=searchnode(head,number);
print(head);break;
case 5:DeleteMemory(head);
printf("t!!\n");break; /*释放head指向的链表中所有节点占用的内存*/
default:printf("Error!!\n");break;
}
printf("\nplease input 'y' to insert one new list,input 'n' to finish!\n");/*提示是否要继续*/
scanf("%c",&c);getchar();
}while(c=='y'||c=='Y');
}
struct student *creat(void)/*函数功能:创建一个链表存储学生的基本信息*/
{
struct student *head=NULL,*p,*p1; //p为当前正在创建的节点,p1为p的前一节点
int i;
char c;
do
{
printf("please input 'y' to insert one new list,input 'n' to finish!\n");/*提示是否要继续*/
scanf("%c",&c);getchar();
if(c=='n')/*判断用户输入的是否是否*/
break;/*跳出*/
p1=p=(struct student*)malloc(sizeof(struct student));/*开辟一个新结点*/
printf("plaese input the student's number\n");
scanf("%ld",&p->number);/*输入该生的学号*/
printf("plaese input the student's name\n");
scanf("%s",p->name);getchar();/*输入名字*/
for(i=0;i<M;i++)
{
printf("please input the student's score\n");
scanf("%f",p->score+i);getchar();/*输入分数*/
}
p->next=NULL;
if(head==NULL)/*判断是否为第一个结点*/
head=p;/*使指向第一个结点*/
else
p1->next=p;/*连接结点*/
p1=p;
}while(1);/*继续*/
return head;
}
/*函数功能:输出链表的内容,同时输出每个学生的总分和平均分*/
void print(struct student *head)
{
struct student *p;
int i;
p=head;
if(head!=NULL)/*判断是否为空链表*/
{
printf("学号\t姓名\t科目1\t科目2\t科目3\t总分\n");
do
{
printf("%ld\t",p->number);/*输出该生的学号*/
printf("%s\t",p->name);/*输出该生的名字*/
for(i=0;i<M;i++)
{
printf("%d\t",p->score[i]);
}
SUM(p);
printf("%d\n",p->sum);//输出sum
p=p->next;/*使指向下一个结点*/
}while(p!=NULL);/*判断是否为链表的尾点*/
}
else
printf("没有信息,无法输出\n");
}
/*函数功能:修改指定的某个学生的信息*/
struct student *xiugai(struct student * head)
{
int j;
long changenumber;
struct student *newnode;
printf("please input the student's number who you want to change");/*提示用户输入想要修改的学生的学号*/
scanf("%ld",&changenumber);/*输入学生的学号*/
newnode=searchnode(head,changenumber);/*调用函数找到想要修改的学生的学号该结点的地址*/
if(newnode==NULL)
printf("Not find");/*输出没有找到*/
printf("please input the name that you want to change");/*提示输入修改的名字*/
scanf("%s",newnode->name);/*输入名字*/
for(j=0;j<M;j++)
{
printf("please iuput the student's score who you want to change");/*输入想要修改的分数*/
scanf("%f",&newnode->score[j]);/*分数*/
}
return head;/*返回修改后的链表的头指针*/
}
/*函数功能:删除某一节点*/
struct student *del(struct student *head,long num) //按输入的学号查找并删除
{
struct student *p,*pr;
if(head==NULL) //链表为空的情况
{
printf("List is NULL\n");
return (head);
}
if(head->number==num) //如果要删除的学号正好是第一个
{
p=head;
head=head->next;
free(p);
}
else
{
pr=head;p=head->next;
while(p!=NULL&&p->number!=num)
{pr=p;p=p->next;}
if(pr!=NULL)
{pr->next=p->next;free(p);}
else
printf("NO FINDING!\n");
}
return(head);
}
/*函数功能:添加某一节点,插入stu节点*/
struct student *insert(struct student *head,struct student *stu,int i)
{
struct student *p,*pre; //pre为p的前一节点
if(head==NULL) /*链表为空时*/
if(i==1)/*链表为空时,插入在head后,即第一个*/
{head=stu;}
else
printf("出界!\n");
else /*链表不为空时*/
{
if(i==1)/*链表不为空时,插入在head后,即第一个*/
{stu->next=head; head=stu;}
else
{
pre=head; //从head开始
p=head->next; //head的next开始
for( ;p->next!=NULL&&i>2;pre=pre->next,p=p->next,i--);//往后数到第i个位置
if(p==NULL) //若在第i个位置没有节点
printf("出界!\n"); //输入的数据太大,超出链表的范围
else
{stu->next=p;pre->next=stu;} //插入
}
}
return(head);
}
/*函数功能:查找指定学号的结点*/
struct student *searchnode(struct student *head,long num)
{
struct student *p;
p=head;
while(p!=NULL)/*表尾时结束*/
{
if(p->number==num)/*判断是否是想要查找的学生的学号*/
{
return p;
}
p=p->next;/*后移一个位置*/
}
return NULL;
}
/*函数功能:求一个学生总分(一个结点p的zongfen)*/
void SUM(struct student *p)
{
int i;
p->sum=0;
for(i=0;i<M;i++)
p->sum+=p->score[i];
}
/*函数功能:释放head指向的链表中所有节点占用的内存*/
void DeleteMemory(struct student *head)
{
struct student *p=head, *pr=NULL;
while (p!=NULL)
{
pr=p;
p=p->next;
free(pr);