数据结构有人熬过了复杂度,熬过了顺序表,就卡在链表这里,其实也不难,我也是菜鸟,所以我会用通俗易懂的东西给大家解释!这里我们先实现一个单链表!
结点:有指针域和数据域
下面我们先了解一下链表的逻辑结构和物理结构以便理解:
逻辑结构:
知道原理结构之后我们开始写代码:
1、定义结点
2、创建main函数:
可以再弄一个testList函数,就不会太多函数在main函数里面了:首先链表为空 直接初始化
3、插入数据,这里使用的是尾插法
至于这里要传二级指针,因为要改变链表里面的数据
传的是地址,因为是SLnode*list 传的是&list 也就是要用二级指针接收 形参与实参的关系在指针的学习已经有了初步的了解,如果是传值的话就用一级指针接收
下面举个例子:
如果实参是int类型 要改变实参,要传int*类型
如果实参是int*类型,就要传int**类型
接下来是打印数据:
这个很简单 不用说了!
4、删除数据 找到某值然后删除
完整代码:
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
//定义节点结构
typedef struct SLnode
{
int data;
struct SLnode* next;
}SLnode;
//插入数据
void SLnodePushBack(SLnode** list, int x)
{
//创建结点 取值
SLnode* newnode = (SLnode*)malloc(sizeof(SLnode));
newnode->data = x;//赋值
newnode->next = NULL;//新节点指向NULL
//判断是否为空
if (*list == NULL)
{
*list = newnode;//将新节点的地址给list
}
else //如果不是空,那么创建一个移动指针,指到最后一个结点 再插入数据
{
SLnode* move = *list;//将list的地址传给move 作为移动
while (move->next != NULL)
{
move = move->next;//指针移动
}
//移动到了最后一个结点
move->next = newnode;//移动指针的next里存的是newnode的地址,算是连接上
move = newnode;//move更换结点 跳到了newnode上
}
}
//打印数据
void SLnodeprint(SLnode* list)
{
SLnode* tail = list;//创建一个指针遍历链表
while (tail != NULL)
{
printf("%d->", tail->data);
tail = tail->next;
}
printf("NULL\n");
}
//删除数据
void SLnodePopBack(SLnode** list, int x)
{
//创建一个临时指针 遍历到x的位置 然后删除
//assert(*list != NULL);//断言 如果是NULL直接退出 很粗暴
//这种比较温柔
if (*list == NULL)
{
return;
}
SLnode* pend = *list;
if (pend->data == x)//如果头结点==x
{
*list = pend->next;//那么链表的头就是pend的下一个结点
}
else
{
//SLnode* pend = *list;
SLnode* perv = pend->next;//创建一个临时指针,来遍历链表
while (perv != NULL)
{
if (perv->data == x)
{
pend->next = perv->next;//将pend的next的地址获取的是perv的next里的地址
free(perv);//再释放结点
perv = pend->next;//将pend->next的地址传给perv
}
else
{
pend = pend->next;
perv = perv->next;
}
}
}
}
void testList()
{
SLnode* list = NULL;//首先链表为空 无头结点
//SLnodePushBack(&list, 1);//插入数据
SLnodePushBack(&list, 1);//插入数据
SLnodePushBack(&list, 2);//插入数据
SLnodePushBack(&list, 3);//插入数据
SLnodeprint(list);//链表的打印
//SLnodePopBack(&list, 3);//删除数据
SLnodePopBack(&list, 2);//删除数据
SLnodePopBack(&list, 1);//删除数据
SLnodeprint(list);//链表的打印
}
int main()
{
testList();
return 0;
}
到这里单链表就创建成功了,看完之后你还觉得难吗?有疑惑的,或者有错误的地方还请指出!
谢谢!