1 – 单链表概念
链式存储结构的线性表
线性表:数据都是一对一的
链式存储:不需要开辟一块连续的空间,将数据进行存储
链式存储通常数据称之为结点,结点由数据域和指针域组成,数据域保存数 据指针域保存下一个结点的地址
2 – 单链表的操作
(1)定义一个结点结构体
typedef int data_t;
//定义一个结点结构体
typedef struct node{
data_t data; //数据域
struct node *next; //指针域,保存下一个结点的地址
//又能操作下一个结点,所以定义一个当前结构体类型的指针变量
}linklist;
(2)创建一个空的单链表
//创建一个空的单链表
//定义一个当前结点结构体类型的指针变量并将其保存NULL来标识为空
linklist *Head = NULL;
(3)头插法插入数据
//头插法插入数据
void InsertData(linklist **head, data_t value)
{
//在堆区开辟空间,可以手动申请手动释放
linklist *temp = (linklist *)malloc(sizeof(linklist));
temp->data = value;
temp->next = NULL;
//先判断一下链表中是否有数据
//如果没有数据,直接保存新插入结点的地址
if(*head == NULL)
{
*head = temp;
}
//如果有数据,按照头插法插入
else
{
temp->next = *head;
*head = temp;
}
}
(4)打印数据
//打印数据
void PrintData(linklist *head)
{
//当链表不为空是打印每一个结点的数据,为空则结束
while(head != NULL)
{
//先打印当前head指向的结点的数据
printf("%d ", head->data);
//head指针后移保存下一个结点的地址
head = head->next;
}
putchar(10);
return ;
}
(5)尾插法插入数据
//尾插法插入数据
void InsertDataByTail(linklist **head, data_t value)
{
//申请空间并赋值
linklist *temp = (linklist *)malloc(sizeof(linklist));
temp->data = value;
temp->next = NULL;
if(*head == NULL)
{
*head = temp;
}
else
{
linklist *p = *head;
//找到最后一个结点
while(p->next != NULL)
{
p = p->next;
}
//最后一个结点的指针域保存新插入结点的地址
p->next = temp;
}
return ;
}
(6)头删法删除数据
//头删法删除数据
data_t DeleteDataByHead(linklist **head)
{
if(*head == NULL)
{
printf("链表中已经没有数据了\n");
return -1;
}
//定义变量保存要删除的结点的地址,方便于释放空间
linklist *p = *head;
//保存要删除的结点的数据域
data_t value = p->data;
//让head保存下一个结点的地址
*head = (*head)->next;
free(p);
p = NULL;
return value;
}
(7)修改数据,按照数据修改数据,将旧的数据修改为新的
//修改数据,按照数据修改数据
void ChangeData(linklist **head, data_t old_value, data_t new_value)
{
linklist *p = *head;
int flags = 0;
while(p != NULL)
{
if(p->data == old_value)
{
p->data = new_value;
flags = 1;
}
p = p->next;
}
if(flags == 0)
{
printf("%d不存在!\n", old_value);
}
return ;
}
(8)查找数据,按照数据查找位置,返回数据的位置
//按照数据查找位置
int getPosByData(linklist *head, data_t value)
{
int pos = 0;
while(head != NULL)
{
if(head->data == value)
{
return pos;
}
head = head->next;
pos++;
}
printf("%d不存在\n", value);
return -1;
}
(9)插入数据并排序
//插入并排序
void InsertDataAndSort(linklist **head, data_t value)
{
//申请空间并赋值
linklist *temp = (linklist *)malloc(sizeof(linklist));
temp->data = value;
temp->next = NULL;
if(*head == NULL)
{
*head = temp;
}
else
{
//如果head的数据大于新插入结点的数据,使用头插法插入数据
if((*head)->data > temp->data)
{
temp->next = *head;
*head = temp;
}
else
{
//定义一个指针变量保存第一个结点的地址
linklist *p = *head;
//比较p的下一个结点的数据与新插入的结点的数据的关系
//如果一直是小,则一直后移,直到找到的大的,则将新插入的结点插入到p的后面
//如果链表到头了,将其插入到最后面
while( p->next != NULL && p->next->data < temp->data)
{
p = p->next;
}
//将p的后一个结点的地址保存在新插入结点的指针域中
temp->next = p->next;
//将新插入结点的地址保存在p结点的指针域中
p->next = temp;
}
}
return ;
}