一,链表
1.1定义
1
)
定义:
1)定义:
1)定义:线性表的链式存储就是链表,链表与顺序表(数组)的局别在于,数组的存储是连续的,而链表的存储是通过指针前后进行链接,就像铁链一样,他们的物理存储空间不是连续的。
1
)
分类:
1)分类:
1)分类: 链表分为单链表和双向链表以及循环链表(本次不讲)
二,单链表
1
)
定义:
1)定义:
1)定义:为了反映数据之间的逻辑关系,对于每个数据不仅仅要表示他的具体内容,而且还要附加一个表示他的后继存储元素存储位置的信息,以便分别前后连接在一起,形成链表。
比如 :我们有一个结构体变量(链表常用结构体类型)
S
t
r
u
c
t
S
t
u
d
e
n
t
Struct Student
StructStudent
{
i
n
t
int
int
n
u
m
num
num //数据域
f
l
o
a
t
float
float
s
c
o
r
e
score
score //数据域
S
t
r
u
c
t
S
t
u
d
e
n
t
Struct Student
StructStudent
∗
n
e
x
t
*next
∗next //指针域
}
由数据域与指针域这样构成的单向链表称为单链表
其中,
n
e
x
t
next
next指针变量指向下一个
S
t
r
u
c
t
S
t
u
d
e
n
t
Struct Student
StructStudent的结构体
2.1单链表的定义
其中
n
u
m
,
S
c
o
r
e
num,Score
num,Score为数据域,
∗
n
e
x
t
*next
∗next为指针域
1
)
源码:
1)源码:
1)源码:
struct Student{
int num;//number
float score;
struct Student *next;
};
struct Student{
int num;//number
float score;
struct Student *next;
};
2.2单链表的初始化
1
)
说明
:
1)说明:
1)说明:
单链表的初始化,即构造一个包含头结点的空单链表。其过程是首先申请一个节点让指针head指向该节点,然后将它的指针域指向空(NULL),最后返回头指针。
1 ) 源码 : 1)源码: 1)源码:
//创建单链表节点,返回头指针
struct Student *initial()
{
struct Student *head;
head=(struct Student *)malloc(sizeof( struct Student));
head->next=NULL;
return head;
}
2.3单链表的建立
1
)
说明
:
1)说明:
1)说明:
尾插法建立链表可以实现次序一致。该算法从空表开始,借用一个指针(命名为Last),使其指向当前链表的尾节点。开创了一个新节点后,把s赋值给last指向的next,然后,再last赋值给S即可。
1
)
源码
:
1)源码:
1)源码:
//尾插法建立链表
void creat_list( struct Student *head ,int n)
{
struct Student *s,*last;
int i ;
last=head;
printf("请你输入%d个整数\n",n);
for(i=0;i<n;i++)
{
s=(struct Student *)malloc(sizeof(struct Student));
scanf("%d,%f",&s->num,&s->score);
printf("请你再输入一次\n");
s->next=NULL;
last->next=s;
last=s;
}
printf("输入完成");
}
2.4求表长操作
1
)
说明
:
1)说明:
1)说明:
因为链表是链式结构,其链表中的元素个数不是已知的。所以想求表中的元素个数还需要进行循环计数。
1
)
源码
:
1)源码:
1)源码:
//列表的求长
int length_count(struct Student *head)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=0;//计数变量
while(p!=NULL)
{
p= p->next;
j++;
}
return j;
}
2.5输出列表
1
)
说明
:
1)说明:
1)说明:
单链表扫描,比较简单。
2
)
源码
:
2)源码:
2)源码:
//列表的输出
void disp(struct Student *head)
{
struct Student * p;
p=head->next;
while(p!=NULL)
{
printf("%d, %f\n",p->num,p->score);
p=p->next;
}
}
2.5链表插入
1 ) 说明 : 1)说明: 1)说明:
2 ) 源码 : 2)源码: 2)源码:
//链表的插入
void insert_in(struct Student *head,int i)
{
//插入的主要思想是
/*第一步:生成的节点指向所原来所插入后的节点s->next=p->next
第二步:将P->next=s,将本节点连接到要插入的节点后面*/
struct Student *p,*s;
p=head;
int j=0;
/**< 定位到那个插入点 */
while(p->next!=NULL && j<i)
{
p= p->next;
j++;
}
if(p!=NULL)
{
printf("请你输入要插入的元素\n");
s=(struct Student *)malloc(sizeof(struct Student));
scanf("%d,%f",&s->num,&s->score);
s->next=p->next;
p->next=s;
printf("插入元素成功\n");
}
}
2.6链表查找
1
)
说明
:
1)说明:
1)说明:查找对于原因(具体见代码)
2
)
源码
:
2)源码:
2)源码:
//按值查找链表
void Locate(struct Student *head,int numb)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=1;
//链表中查找到不是表尾和数据不是指定的num时候
while(p->next!=NULL && p->num!=numb)
{
p= p->next;
j++;
}
if(p!=NULL)
printf("你所找的数据已经找到,在表的第%d位,数据为%d\n",j,numb);
else
printf("我没有找到你想要的数据\n");
}
//按位置查找
void SearchList(struct Student *head,int i)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=1;
if(i>length_count(head))
printf("超过了链表长度,没有链表的位置\n");
else
while(p->next!=NULL && j<i)
{
p= p->next;
j++;
}
if(i=j)
printf("你所找的数据已经找到,在表的第%d位,数据为%d,%f\n",j,p->num,p->score);
}
总源码
//对于指针的联系
//单链表建立之后插法
#include <stdio.h>
#include <stdlib.h>
struct Student{
int num;//number
float score;
struct Student *next;
};
//创建单链表节点,返回头指针
struct Student *initial()
{
struct Student *head;
head=(struct Student *)malloc(sizeof( struct Student));
head->next=NULL;
return head;
}
//尾插法建立链表
void creat_list( struct Student *head ,int n)
{
struct Student *s,*last;
int i ;
last=head;
printf("请你输入%d个整数\n",n);
for(i=0;i<n;i++)
{
s=(struct Student *)malloc(sizeof(struct Student));
scanf("%d,%f",&s->num,&s->score);
printf("请你再输入一次\n");
s->next=NULL;
last->next=s;
last=s;
}
printf("输入完成");
}
//列表的输出
void disp(struct Student *head)
{
struct Student * p;
p=head->next;
while(p!=NULL)
{
printf("%d, %f\n",p->num,p->score);
p=p->next;
}
}
//列表的求长
int length_count(struct Student *head)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=0;//计数变量
while(p!=NULL)
{
p= p->next;
j++;
}
return j;
}
//按值查找链表
void Locate(struct Student *head,int numb)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=1;
//链表中查找到不是表尾和数据不是指定的num时候
while(p->next!=NULL && p->num!=numb)
{
p= p->next;
j++;
}
if(p!=NULL)
printf("你所找的数据已经找到,在表的第%d位,数据为%d\n",j,numb);
else
printf("我没有找到你想要的数据\n");
}
void SearchList(struct Student *head,int i)
{
struct Student * p=head->next;//定义一个结构体指针,并指向
int j=1;
if(i>length_count(head))
printf("超过了链表长度,没有链表的位置\n");
else
while(p->next!=NULL && j<i)
{
p= p->next;
j++;
}
if(i=j)
printf("你所找的数据已经找到,在表的第%d位,数据为%d,%f\n",j,p->num,p->score);
}
//链表的插入
void insert_in(struct Student *head,int i)
{
//插入的主要思想是
/*第一步:生成的节点指向所原来所插入后的节点s->next=p->next
第二步:将P->next=s,将本节点连接到要插入的节点后面*/
struct Student *p,*s;
p=head;
int j=0;
/**< 定位到那个插入点 */
while(p->next!=NULL && j<i)
{
p= p->next;
j++;
}
if(p!=NULL)
{
printf("请你输入要插入的元素\n");
s=(struct Student *)malloc(sizeof(struct Student));
scanf("%d,%f",&s->num,&s->score);
s->next=p->next;
p->next=s;
printf("插入元素成功\n");
}
}
//链表的删除操作
void delete_list(struct Student *head,int i)
{
int j=0;
int numb;
float score_s;
struct Student *p=head,*s;
printf("你所需要删除的元素是\n");
while(p->next!=NULL && j<i)
{
p= p->next;
j++;
}
if(p->next!=NULL && j==i)
{
s=p->next;
numb=s->num;
score_s=s->score;
p->next=s->next;
s->next=p->next;
free(s);
printf("删除元素成功\n");
}
else
printf("删除节点错误,删除失败");
}
void main()
{
struct Student *head;
head=initial();
creat_list(head,3);
disp(head);
printf("链表的长度为%d个\n",length_count(head));
Locate(head,33);
SearchList(head,2);
insert_in(head,2);
printf("链表的长度为%d个\n",length_count(head));
disp(head);
Locate(head,33);
SearchList(head,2);
delete_list(head,2);
disp(head);
return 0;
}
附录:
附录:
附录: