1.链表的作用
- 链表是动态分配存储空间的链式存储结构
- 链式(元素与元素间没有地址紧邻)存储线性表(具有唯一的前驱与后继)
(前驱与后继实际值结构内部定义的结构体指针)
2.链表存储的含义
- 当一个序列中只含有指向它的后继结点的链接时,称该链表为单链表
- 数据位置不连续,通过指针进行相互关联
- 单链表中第一个节点不存数据,只存指针,称为头指针
- 链表中每个元素称为“结点“,每个节点由数据和指向下一个位置的指针组成
- 最后一个节点的指针指向空
3.增删查改的实例
- 在对链表进行增删查改的操作时,应先定义一个用于进行增删查改的结构体
3.1 定义如下:
typedef struct node
{
int data;//一个数据
struct node* next;指向下一个节点的位置
}//相当于结点
3.2 在定义结点之后要申请为其初始化
NODE* init()
{
NODE* p=(NODE*)malloc(sizeof(NODE));//申请堆内存
p->next=NULL;
return p;
}
3.3 对链表增加元素
图示链表增加元素的过程
代码实现
void insertData(NODE *head,int data)
{
NODE* head=(NODE*)malloc(sizeof(NODE));
head->next=NULL;
NODE* p=(NODE*)malloc(sizeof(NODE));
p->data=data;
p->next=head->next;
head->next=p;
}
4.说明
- 单链表的头结点不存数据
4.1 数组和链表的优缺点
- 增:数组在尾部插入方便,其他位置不方便;链表在任意一个地方都很方便插入
- 删:数组在尾部删除方便,链表在任意地方删除方便
- 改:数组和链表修改都很方便
- 查:有序条件下,数组二分查找比较方便 ,链表只能一步步查找
5.代码实例
#include<stdio.h>
#include<string>
typedef struct node
{
int data;//数据
struct node*next;//指向下一个节点的位置
}NODE;
NODE *init();//初始化操作 给head赋值 也可以用参数的方式给head赋值
void insertData(NODE *head,int data);//给链表赋值,传递需要插入的数据并且传入head指针
void deleData(NODE *head, int data);//
void findData(NODE *head, int data);
void deleALL(NODE *head, int data);
void print(NODE *head);
int main()
{
NODE *head;//头指针 保存一个节点的位置,可以找到所有节点的位置,如果想在其他函数中修改head指针,那么需要传递head的地址
head = init();
for (int i = 0; i < 10; ++i)
{
insertData(head, i);
}
//insertData(head, 23);
print(head);
getchar();
return 0;
}
NODE *init()
{
NODE *p = (NODE *)malloc(sizeof(NODE));
p->next = NULL;
return p;
}
void insertData(NODE *head, int data)
{
//给结构体指针申请一个堆内存
NODE *p = (NODE*)malloc(sizeof(NODE));
p->data = data;
#if 1
//头插方式给数据进行插入
p->next = head->next;
head->next = p;
#else
NODE *q=(NODE*)malloc(sizeof(NODE));
while (q->next != NULL)q = q->next;
q->next = p;
p->next = NULL;
#elseif
NODE *q = head;
for (int i = 0; i < 2; ++i)
{
q = q->next;
}
p->next = q->next;
q -> next = p;
#endif
}
void deleData(NODE *head, int data)
{
NODE *p = head;
while (p != NULL&&p->next!=NULL)
{
if (p->next->data == data)
{
NODE *q = p->next;
p->next = p->next->next;
free(q);
}
else
{
p = p->next;
}
}
}
void findData(NODE *head, int data)
{
//查找在有序的前提下,用二分查找,如果无需还需要排序或者用二叉树等
}
void deleALL(NODE *head, int data)
{
//从头开始删除
NODE *p, *q;
p = head;
while (p != NULL)
{
q = p;
p = p->next;
free(q);
}
}
void print(NODE *head)
{
NODE *p = head;
while (p != NULL)
{
printf("结点地址%p,data=%d,next=%p\n\n", p, p->data, p->next);
p = p->next;
}
}