include <stdio.h>
include <stdlib.h>
//单链表属于一种数据结构
//单链表就像自行车的链条
//定义变量,把他们通过指针连接起来,像自行车的链条一样
//数组的大小不可以改变 数组访问元素可以随机访问
//链表的大小可以改变 链表访问元素不可以随机访问
//单量表的访问,只能由头往尾访问
//知道单链表的结构
/*
- 第一步:创建头结点:通过malloc给结构体指针申请内存,当做头结点,初始化指针
- 第二步:插入数据,通过malloc给结构体指针申请内存,保存数据。在头的后面插入数据(头插),用新节点的next指向头节点的next(保存头节点下一个),头节点的next指向新节点
- 第三步:定义一个指针ptr指向头节点的next(第一个有数据的节点),[判断当前ptr指向的节点是否为空,为空结束函数,不为空,输出当前ptr指向的节点的数据,指针往下一个节点移动]重复上面的过程
- 删除:应为这里单链表,是不能由尾往前访问,所以在删除某个节点的时候,是需要保持这个单链表的结构,比如:删除A节点,那么需要A节点的前一个节点的next指向A节点的下一个节点,然后释放A节点,所以需要有一个指针指向A节点的前面一个节点 定义指针p1指向头,指针p2指向第一个有数据的节点,p1是p2的前一个节点的地址,这样就可以满足上面的删除,删除的是p2指向的节点
*/
//头结点为什么不存数据?
//头结点存数据的话,第一次插入的时候需要对头结点赋值,不需要申请内存
//第二次插入数据,才需要申请内存,这样操作起来就需要判断要不要给头节点赋值
//头结点不存数据,直接插入
typedef struct list
{
//数据域:可以是一个结构体变量
int id;
//int size;
//指针域
struct list* next;
}LIST;
//初始化头结点
LIST* init()
{
LIST* p = (LIST)malloc(sizeof(LIST));
p->next = NULL;
//p->size = 0;
return p;
}
//插入
void insert(LISThead,int data)
{
//如果指针head==NULL就直接退出函数
LISTp= (LIST)malloc(sizeof(LIST));
p->id = data;//接收数据
//指针的连接下去自己必须画图一条线一条线的连
p->next = head->next;
head->next = p;
//head->size++;
}
//输出
void print(LIST* head)
{
//判断指针head==NULL就直接退出函数
LIST* p = head->next;//指向了第一个有数据的节点
while (p != NULL)
{
printf("%d
", p->id);
p = p->next;//往下一个节点移动
}
}
void del(LIST* head, int id)
{
LIST* p1 = head;
LIST* p2 = head->next;
while (p2!=NULL)
{
if (p2->id == id)
{
p1->next = p2->next;
free(p2);
return;
}
p1 = p1->next;
p2 = p2->next;
}
}
void empty(LIST* head)
{
LIST* p = head->next;
while (p!=NULL)
{
head->next = p->next;
free(p);
p = head->next;
}
}
int main()
{
LIST* head = init();
insert(head, 4);
insert(head, 5);
insert(head, 6);
del(head, 5);
print(head);
empty(head);
free(head);
getchar();
getchar();
return 0;
}