您的位置:首页 > 理论基础 > 数据结构算法

数据结构学习二 数据结构之链表代码版【创建,遍历,删除,插入】

2016-07-29 22:35 435 查看
代码:

/******动态链表的建立、删除、插入的完整程序*****/
#include    "stdio.h"
#include    "string.h"
#include    "stdlib.h"
#define Len sizeof(struct student)  //定义一个结构体等长的常量len,用于给新的结构体分配空间
/*********************************
结构体名:student
**********************************/
struct student
{
int num;
int score;
struct student *next;
};//此分号容易忘记!!!
struct student *head,*p1,*p2;//P1指向待插入节点,P2为首节点,head为头结点!
int n=0;   //用于记录插入链表的个数
/*********************************
函数名 :*creat()
参数   :无
功能   :用于插入新的链表
返回值 :返回链表的首地址 head
基本思路:  三个结点(头结点head、尾结点 NULL 和待插入结点 P)
第一步:定义头结点head、尾结点 p2 和待插入结点p1,待插入的结点数据部分初始化;
第二步:P1该结点被头结点、尾结点同时指向。
P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL;
第三步:重复申请待插入结点空间,对该结点的数据部分赋值(或输入值),将该结点插入在最前面,或者最后面(书上在尾部插入).
P2->next=P1;  P2=P1;
第四步:最后:P2->next=NULL;
*********************************/
struct student *creat()
{
//第二步 P1该结点被头结点、尾结点同时指向。P1=p2=(struct student*)malloc(LEN);头指针部分为空,head=NULL;
head=NULL;
p1=(struct student*)malloc(Len);    //插入前先开辟一个空节点位置,给新的节点分配空间
p2=p1;//P1替换掉P2,包括指针域和数据域
//第一步 定义头结点head、尾结点 p2 和待插入结点p1,待插入的结点数据部分初始化;
puts("请输入学生号和成绩");
scanf("%d %d",&(p1->num),&(p1->score));

while(p1->num!=0)
{
n++;
if(n==1) head=p1;
else p2->next=p1;
p2=p1;
p1=(struct student*)malloc(Len);
printf("建立链表%d\n",n);
scanf("%d %d",&(p1->num),&(p1->score));
}
p2->next=NULL;
puts("链表建立结束");
return head;
}
/*******************************************
函数名 :print()
参数  :结构体的首地址 *head1
功能  :输出链表
返回值 : 无
基本思路:传入一个链表的头结点地址,遍历链表即可。
1.单向链表总是从头结点开始的;
2.每访问一个结点,就将当前指针向该结点的下一个结点移动:
p=p->next;
3.直至下一结点为空
P=NULL
*******************************************/
void print(struct student *head1)
{
struct student *p3;
p3=head1;
puts("输出链表");
puts("学号     成绩");
while(p3!=NULL)
{
printf("%d     %d\n",p3->num,p3->score);
p3=p3->next;
}
}
/*******************************************
函数名 :*del()
参数  :链表首地址 *head 以及要删除的学习
学号
功能  :把指定学号的学生信息从链表中
删除掉,
返回值 :返回链表的首地址head
基本思路:两种情况:
1、要删的结点是头指针所指的结点则直接操作;
2、不是头结点,要依次往下找。另外要考虑:空表和找不到要删除的结点
********************************************/
struct student *del(struct student *head ,int num)
{
struct student *sp1,*sp2;
if(head==NULL)  {printf("list is null!"); goto End;}
sp1=head;
while(num!=sp1->num)        //删除的不是所要找的结点
{
sp2=sp1;sp1=sp1->next;  //当节点中的学号不想等时移动指针sp1
}
if(num==sp1->num)
{
if(sp1==head)
{
head=sp1->next;    //若sp1指向的是首结点,把第二个结点地址给head
}
else if(sp1->next==NULL)  /*若sp1指向的最后一个结点,把倒数第二个
sp2->next=NULL作为最后一个结点*/
{
sp2->next=NULL;
}
else
{
sp2->next=sp1->next;   //否则删除sp1所指的结点
}
n--;
printf("已删除%d",num);
}
else printf("找不到该节点\n");
End :;
return head;
}
/********************************************
函数名 :*insert()
参数  :链表首地址*head 和要插入新结点
地址*newstu
功能    :在链表中再插入新的结点
返回值 :返回新的链表首地址head
基本思路:将一个结点插入到已有的链表中
插入原则:
1、插入操作不应破坏原链接关系
2、插入的结点应该在它该在的位置
实现方法:
应该有一个插入位置的查找子过程
共有三种情况:
1、插入的结最小
2、插入的结点最大
3、插入的结在中间

同删除一样,需要几个临时指针:
P0: 指向待插的结点;初始化:p0=数组stu;
P1: 指向要在P1之前插入结点;初始化: p1=head;
P2: 指向要在P2之后插入结点;
插入操作:当符合以下条件时:p0->num 与 p1->num 比较找位置
if(p0->num>p1->num)&&(p1->next!=NULL)  则插入的结点不在p1所指结点之前;指针后移,交给p2;
p1= p1->next;
p2=p1;
则继续与p0指向的数组去比,直到(p1->next!=NULL)为止。
否则有两种情况发生:
if(head==p1) head=p0;p0->next=p1插到原来第一个结点之前;
else p2->next=p0;p0->next=p1; 插到 p2 指向的结点之后;
还有另外一种情况:插到最后的结点之后;
p1->next=p0;p0->next=NULL;
*********************************************/
struct student *insert(struct student *head,
struct student *newstu)
{
struct student *p0,*sp1,*sp2;
sp1=head;                     //使sp1指向第一个结点
p0=newstu;                   //使p0指向新结点的地址
if(head==NULL)               //原来的链表是空的
{
head=p0;
p0->next=NULL;
}
else
{
while(sp1->num<p0->num&&sp1->next!=NULL)
{
sp2=sp1;             //使sp2指向刚才sp1的结点,移动sp1指针到下一个结点
sp1=sp1->next;
}
if(p0->num<sp1->num)
{
if(head==sp1)
{
head=p0;         //插入到原来第一个结点之前
p0->next=sp1;    //让新的结点指向第一个结点
}
else
{
sp2->next=p0;    //否则插入到sp2和sp1之间
p0->next=sp1;
}
}
n++;
}
return head;         //返回新的首地址;
}

void main()
{
struct student *p,newstu;
int num;
puts("创建链表");
p=creat();           //创建链表
print(p);            //输出全部链表
puts("请输入要删除的学号");
scanf("%d",&num);
p=del(p,num);        // 删除链表
print(p);
puts("请输入插入学生的学号和成绩");
scanf("%d %d",&newstu.num,&newstu.score);
p=insert(p,&newstu);    //插入链表
print(p);
print(p);
free(p1);
free(p2);
free(head);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 链表 遍历
相关文章推荐