目录
概念:
链表 - 内存空间开辟不是连续、通过地址将多有的内存空间练习到一起
逻辑结构:线性结构
存储结构:链式存储
单向链表:
1、 有头单向链表
链表中的头节点数据域无效,指针域有效。
2、 无头单向链表
链表中所有节点的数据域和指针域都是有效的。
定义链表节点结构体:
typedef int datatype_t;
typedef struct node_t //node 节点
{
datatype_t data;//数据域
struct node_t *next;//指针域 保存下一个节点的地址
}linklist_t,*linklist_p;
链表的特点
1.内存空间不连续,通过地址将地址空间联系在一起
2.长度不固定
3.删除和插入简单,查询和修改复杂
链表的操作:有头单向链表
1. 创建空间有头单向链表
2. 向链表的指定位置插入数据
3. 计算链表的长度
4. 遍历链表
5. 删除链表指定位置的数据
6. 修改链表指定位置的数据
7. 查询指定数据的位置
8. 删除指定的数据
9. 清空链表
10.链表倒置
代码:(分文件)
头文件:定义结构体,声明函数
#ifndef __LINK_H__
#define __LINK_H__
typedef int datatype_t;
typedef struct node_t
{
datatype_t data;
struct node_t *next;
}linklist_t,*linklist_p;
linklist_t *createEmptyLink(void);//1.创建空间有头单向链表
int insertPost(int post, datatype_t data, linklist_t *p);//2、指定位置插入
int lenLink(linklist_t *p); //3.计算链表的长度
int showLink(linklist_t *p);//4.遍历链表
int deletePostData(int post,linklist_t *p);//5.删除链表指定位置的数据
int changeData(int post, datatype_t data, linklist_t *p); //6.修改链表指定位置的数据
int search(datatype_t data,linklist_t *p); //7.查询指定数据的位置
void deleteData(datatype_t data, linklist_t *p);//8.删除指定的数据
void clearLinkList(linklist_t *p);//9.清空链表
void daozhiLinkList(linklist_t *p); //10、链表倒置
#endif
链表操作函数接口
#include <stdio.h>
#include "link.h"
#include "stdlib.h"
linklist_t *createEmptyLink(void) //1.创建空间有头单向链表
{
linklist_t *p = (linklist_t *)malloc(sizeof(linklist_t));
if (NULL == p)
{
printf("malloc head node err.\n");
return NULL;
}
p->next = NULL;
return p;
}
int insertPost(int post, datatype_t data, linklist_t *p) //2、指定位置插入
{
if (post < 0 || post > lenLink(p))
{
printf("insert error\n");
return -1;
}
linklist_t *pnew = (linklist_t *)malloc(sizeof(linklist_t));
if (pnew == NULL)
{
printf("error\n");
return -1;
}
pnew->data = data;
pnew->next = NULL;
for (int i = 0; i < post; i++)
p = p->next;
pnew->next = p->next;
p->next = pnew;
return 0;
}
int lenLink(linklist_t *p) //3.计算链表的长度
{
int len = 0;
while (p->next != NULL)
{
p = p->next;
len++;
}
return len;
}
int showLink(linklist_t *p) //4.遍历链表
{
while (p->next != NULL)
{
p = p->next;
printf("%d ", p->data);
}
putchar(10);
return 0;
}
int deletePostData(int post, linklist_t *p) //5.删除链表指定位置的数据
{
if (post < 0 || post >= lenLink(p))
{
printf("deletedata error\n");
return -1;
}
linklist_t *q = NULL;
for (int i = 0; i < post; i++)
p = p->next;
q = p->next;
p->next = q->next;
free(q);
q = NULL;
return 0;
}
int changeData(int post, datatype_t data, linklist_t *p) //6.修改链表指定位置的数据
{
if (post < 0 || post >= lenLink(p))
{
printf("xiugaidata error\n");
return -1;
}
for (int i = 0; i <= post; i++)
p = p->next;
p->data = data;
return 0;
}
int search(datatype_t data, linklist_t *p) //7.查询指定数据的位置
{
if (p->next == NULL)
{
printf("search err\n");
return -1;
}
int i = 0;
while (p->next != NULL)
{
p = p->next;
if (p->data == data)
return i;
i++;
}
return -1;
}
void deleteData(datatype_t data, linklist_t *p) //8.删除指定的数据
{
if (p->next == NULL)
printf("deleteData err\n");
linklist_t *pdel = NULL;
while (p->next != NULL)
{
if (p->next->data == data)
{
pdel = p->next;
p->next = pdel->next;
free(pdel);
pdel = NULL;
}
else
p = p->next;
}
}
void clearLinkList(linklist_t *p) //9.清空链表
{
while (p->next != NULL)
deletePostData(0, p);
}
void daozhiLinkList(linklist_t *p)//10、链表倒置
{
linklist_t *pt = p->next;
linklist_t *ph = NULL;
p->next=NULL;
while (pt != NULL)
{
ph = pt;
pt = pt->next;
ph->next = p->next;
p->next = ph;
}
}
主函数:调用函数
#include "stdio.h"
#include "link.h"//调用写好的头文件
int main(int argc, char const *argv[])
{
linklist_t *p = createEmptyLink();
//指定位置插入
insertPost(0, 10, p);
insertPost(1, 20, p);
insertPost(2, 30, p);
insertPost(3, 40, p);
insertPost(4, 50, p);
showLink(p);
deletePostData(0,p);//指定位置删除
showLink(p);
changeData(2,1000,p);//修改数据
showLink(p);
int t=search(300,p);//查询
printf("%d\n",t);
deleteData(20,p);//删除指定数据
showLink(p);
daozhiLinkList(p);//链表倒置
showLink(p);
clearLinkList(p);//清空链表
showLink(p);
return 0;
}