链表
动态进行存储的分配的数据结构;
含head、结点(实际数据+下一结点地址);
1.以指针定义单结点、双结点链表
```c
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node *next;
} ;//*结构体建立最简单的链表*
int main()
{
struct node *p;//使用指针需先分配动态存储
p=(node*)malloc(sizeof(node));//*开辟动态内存区,地址转换成node*型,放入p*
p.data=1;
}
malloc函数-动态分配空间size个字节,malloc(size),返回void指针,因此需要基类型申明(node)-结构体类型
```c
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node *next;
} ;
int main()
{
struct node *head,*p1,*p2;
p1=(node *)malloc(sizeof(node));
p2=(node *)malloc(sizeof(node));
(*p1).data=1;
(*p2).data=2;
p1->next=p2;//第二结点的地址信息p2赋给第一结点的next成员
p2->next=NULL// NULL作为最后一个结点的标志
head=p1;//定义链表头-第一结点的地址信息
}
2.利用循环语句,实现多结点的初始化
```c
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node *next;
} ;
int main()
{
struct node *head,*p1,*p2;
int i;
head=0;
for(i=0;i<=5;i++)//链表初始化
{
p1=(node *)malloc(sizeof(node));//循环获得新的地址(空间分配)
(*p1).data=i;
if(head==0)//head为表头,则将第一结点地址赋给head和p2
{head=p1;
p2=p1;}
else//此时已开辟新的地址(第二结点)给p1,存进第一结点的(p2)的next成员,然后p2存了第二节点的地址,循环下去
{p2->next=p1;
p2=p1;}
}
//输出链表数据
p2->next=0;
struct node *p;
p=head;
while(p!=0)
{printf("%d",p->data);
p=p->next;}
printf("\n");
}
`
3.删除链表中的结点
```c
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
node *next;
} ;
int main()
{
struct node *head,*p1,*p2;
int i;
head=0;
for(i=0;i<=5;i++)//链表初始化
{
p1=(node *)malloc(sizeof(node));
(*p1).data=i;
if(head==0)
{
head=p1;
p2=p1;
}
else
{
p2->next=p1;
p2=p1;
}
}
p2->next=0;
//删除数据为2的结点
p1=head;
while(p1->data!=2)
{
p2=p1;
p1=p1->next;
}
p2->next=p1->next;//找到要删除的结点,p1.next的地址直接跳给p2.next,这也是链表的优势所在
free(p1);//释放此时p1指向的动态空间
//输出链表数据
struct node *p;
p=head;
while(p!=0)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
return 0;
}
free()函数释放内存。