完整链表

/*
 * 2.cpp
 *
 *  Created on: 2011-8-16
 *      Author: san
 *      链表的建立,输出,删除,插入
 *      11时42分38秒
 *      可以同时删除多个记录,插入多个记录请参考谭浩强主编《c语言程序设计》第三版,第307页
 */


# include <stdio.h>
# include <malloc.h>
# define LEN sizeof(struct student)


struct student
{
long num;
float score;
struct student * next;
};
int n;


//定义函数,创建链表,带回一个指向链表头的指针
struct student * creat(void)
{
struct student * head;
struct student * p1;
struct student * p2;//p1和p2是指向struct student 类型数据的指针
n = 0;
p1 = p2 =(struct student *)malloc(LEN);//malloc 带回的是不指向任何数据类型的指针(void *)
scanf("%ld,%f", &p1->num,&p1->score);
head = NULL;//head指空,没有结点
while (p1->num != 0)
{
n = n + 1;
if (n == 1)
head = p1;//head指向第一个结点
else
p2->next = p1;//当开辟第二个结点及以后的结点时,链接起来
p2 = p1;//p2 指向刚开辟的新的结点
p1 = (struct student *)malloc(LEN);//继续开辟,(struct student *)是强制转换
scanf("%ld,%f", &p1->num,&p1->score);


}
p2->next = NULL;
return(head);


}


//定义链表的输出函数
void print(struct student * head)
{
struct student * p;
printf("\nNow,these %d records are:\n", n);
p = head;//p指向第一个结点
if (head != NULL)
do
{
printf("%ld%5.1f\n", p->num, p->score);
p = p->next;//p指向下一个结点
}while (p != NULL);
}


//定义删除链表中结点的函数
struct student *del(struct student * head, long num)
{
struct student * p1;
struct student * p2;
if (head == NULL)
{
printf("\nlist null!\n");//空表
goto p;
}
p1 = head;
while (num != p1->num && p1->next != NULL)//p1指向的不是要找的结点,并且后面还有结点
{
p2 = p1;//p2保存的是已检查过的结点
p1 = p1->next;//p1向后移一个结点
}
if (num == p1->num)//找到啦
{
if (p1 == head)//要删除的是第一个结点
head = p1->next;//head指向的是下一个结点,删除第一个结点
else
p2->next = p1->next;//将下一结点的地址赋给前一结点的地址,删除此结点
printf("delete:%ld\n", num);
n = n - 1;
}
else
printf("%ld not found!", num);//无此结点
//end;
p:return(head);
}


//定义插入结点的函数
struct student * insert(struct student * head, struct student * stud)
{
struct student * p0;//p0待插入的结点
struct student * p1;//p1第一个结点
struct student * p2;
p1 = head;
p0 = stud;
if (head == NULL)//空表
{
head = p0;//p0指向的结点为头结点
p0->next = NULL;
}
else
{
while ((p0->num > p1->num) && (p1->next != NULL))//待插入的结点不在p1所指结点之前
{
p2 = p1;
p1 = p1->next;//将p1后移,并且使p2指向刚才p1所指的结点
}
if (p0->num <= p1->num)
{
if (head == p1)//插入到最前面的情况
head = p0;
else
p2->next = p0;//p2->next指向插入的结点p0,p0->next指向p1
p0->next = p1;
}
else
{
p1->next = p0;//p0插入到最后面的情况
p0->next = NULL;
}


}
n = n + 1;
return(head);
}


int main(void)
{
struct student * head;
struct student * stu;
long del_num;




printf("please input the records:\n");
head = creat();
print(head);


printf("\nplease input the deleted number:");
scanf("%ld", &del_num);
while (del_num != 0)
{
head = del(head, del_num);
print(head);
printf("\nplease input the deleted number:");
scanf("%ld", &del_num);
}


printf("\nplease input the inserted record:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
while (stu->num != 0)
{


head = insert(head, stu);
print(head);
printf("\nplease input the inserted record:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
}
return 0;
}

/*
 * 2.cpp
 *
 *  Created on: 2011-8-16
 *      Author: san
 *      链表的建立,输出,删除,插入
 *      11时42分38秒
 *      可以同时删除多个记录,插入多个记录请参考谭浩强主编《c语言程序设计》第三版,第307页
 */


# include <stdio.h>
# include <malloc.h>
# define LEN sizeof(struct student)


struct student
{
long num;
float score;
struct student * next;
};
int n;


//定义函数,创建链表,带回一个指向链表头的指针
struct student * creat(void)
{
struct student * head;
struct student * p1;
struct student * p2;//p1和p2是指向struct student 类型数据的指针
n = 0;
p1 = p2 =(struct student *)malloc(LEN);//malloc 带回的是不指向任何数据类型的指针(void *)
scanf("%ld,%f", &p1->num,&p1->score);
head = NULL;//head指空,没有结点
while (p1->num != 0)
{
n = n + 1;
if (n == 1)
head = p1;//head指向第一个结点
else
p2->next = p1;//当开辟第二个结点及以后的结点时,链接起来
p2 = p1;//p2 指向刚开辟的新的结点
p1 = (struct student *)malloc(LEN);//继续开辟,(struct student *)是强制转换
scanf("%ld,%f", &p1->num,&p1->score);


}
p2->next = NULL;
return(head);


}


//定义链表的输出函数
void print(struct student * head)
{
struct student * p;
printf("\nNow,these %d records are:\n", n);
p = head;//p指向第一个结点
if (head != NULL)
do
{
printf("%ld%5.1f\n", p->num, p->score);
p = p->next;//p指向下一个结点
}while (p != NULL);
}


//定义删除链表中结点的函数
struct student *del(struct student * head, long num)
{
struct student * p1;
struct student * p2;
if (head == NULL)
{
printf("\nlist null!\n");//空表
goto p;
}
p1 = head;
while (num != p1->num && p1->next != NULL)//p1指向的不是要找的结点,并且后面还有结点
{
p2 = p1;//p2保存的是已检查过的结点
p1 = p1->next;//p1向后移一个结点
}
if (num == p1->num)//找到啦
{
if (p1 == head)//要删除的是第一个结点
head = p1->next;//head指向的是下一个结点,删除第一个结点
else
p2->next = p1->next;//将下一结点的地址赋给前一结点的地址,删除此结点
printf("delete:%ld\n", num);
n = n - 1;
}
else
printf("%ld not found!", num);//无此结点
//end;
p:return(head);
}


//定义插入结点的函数
struct student * insert(struct student * head, struct student * stud)
{
struct student * p0;//p0待插入的结点
struct student * p1;//p1第一个结点
struct student * p2;
p1 = head;
p0 = stud;
if (head == NULL)//空表
{
head = p0;//p0指向的结点为头结点
p0->next = NULL;
}
else
{
while ((p0->num > p1->num) && (p1->next != NULL))//待插入的结点不在p1所指结点之前
{
p2 = p1;
p1 = p1->next;//将p1后移,并且使p2指向刚才p1所指的结点
}
if (p0->num <= p1->num)
{
if (head == p1)//插入到最前面的情况
head = p0;
else
p2->next = p0;//p2->next指向插入的结点p0,p0->next指向p1
p0->next = p1;
}
else
{
p1->next = p0;//p0插入到最后面的情况
p0->next = NULL;
}


}
n = n + 1;
return(head);
}


int main(void)
{
struct student * head;
struct student * stu;
long del_num;




printf("please input the records:\n");
head = creat();
print(head);


printf("\nplease input the deleted number:");
scanf("%ld", &del_num);
while (del_num != 0)
{
head = del(head, del_num);
print(head);
printf("\nplease input the deleted number:");
scanf("%ld", &del_num);
}


printf("\nplease input the inserted record:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
while (stu->num != 0)
{


head = insert(head, stu);
print(head);
printf("\nplease input the inserted record:");
stu = (struct student *)malloc(LEN);
scanf("%ld,%f", &stu->num, &stu->score);
}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值