无空头的链表操作
#include<stdio.h>
#include<stdlib.h>
void add(int);
void ScanList();
struct node* selectnode(int);
void freelist();
struct node
{
int a;
struct node* pnext;
};
struct node* head = NULL;
struct node* end = NULL;
void add(int a)
{
struct node* p = (struct node*)malloc(sizeof(struct node));
//去接这个节点
p->a = a;
p->pnext = NULL;//不能让这个指针乱指,这里初始话的时候一定要初始
//如果这个不进行初始化的话,这个就会变化野指针
//成空,不然的话会出很多问题,这里初始化成空是为了方便我们后面的遍历
if (head == NULL || end == NULL)
{
head = p;
end = p;
}
else
{
end->pnext = p;//这一步就可以让这个链表连起来
end = p;
}
}
//遍历链表
//也就是查增删改。也可以查指定的
//方法有一个next指针这个指针就是装的下一个节点的,所以我们遍历的时候就要
//通过这个next指针去遍历
void ScanList()
{
struct node* ptemp = head;//首先我们要定义一个中间指针去记住着头指针
//注意这个头指针是千万不能变的,这个头指针用来记住这个开头,如果没有中间变量的话,那么head就会被改变了,就找不到上一个节点了
//我们从头到尾去遍历
while (ptemp != NULL)//这个也是固定的,一个比较精简的写法
{
printf("%d\n", ptemp->a);//这个就是他的数据,这个是无空头的
ptemp = ptemp->pnext;//这个就是我们链表遍历的一个逻辑结构
//注意开始的时候ptemp是这个的头
}
}
//查询指定的节点,可以通过返回值去返回
//步骤基本上都是一样的,但是多了一步我们需要判断的步骤
struct node *selectnode(int a)
{
struct node* ptemp = head;
while (ptemp->pnext != NULL)
{
if (ptemp->a == a)
return ptemp;//就找到了这个节点
ptemp = ptemp->pnext;
}
//没找到,没找到我们就返回NULL
return NULL;
}
//链表清空,释放链表,肯定还是循环,需要一个节一个节点的释放
void freelist()
{
//记录头节点,防止丢失头节点
struct node *ptemp=head;
while (ptemp->pnext != NULL)
{
struct node* pt = ptemp;
//free(ptemp);这样写是不行的,因为如果直接这么写的话,当前的这个节点就直接消失了,
//系统会崩溃的,所以我们要在之后再释放
ptemp = ptemp->pnext;
free(pt);
}
//清空链表
head = NULL;
end = NULL;//这个操作是为了方便下一次的创建
//如果这个不变成null的话,下一次操作的时候,如果head是0x10
//那么下一次操作的时候,这个0x10会保留下来,新来的节点就会接
//到尾巴上
}
void AddListRand(int index, int a)//这个就是再任意的位置添加链表
{
//链表为空
if (NULL == head)
{
printf("链表没有节点\n");
return;
}
//找位置
struct node* pt = selectnode(index);
if (NULL == pt)
{
printf("没有指定节点\n");
return;
}
//有节点
//给a创建一个节点,接下来是创建节点的三个步骤,malloc,赋值,还有把地址写成NULL
struct node* ptemp = (struct node*)malloc(sizeof(struct node));
//给a节点进行赋值
ptemp->a = a;
ptemp->pnext = NULL;
//链接到链表上
if (pt == end)
{
end->pnext = ptemp;
end = ptemp;
}
else
{
//先连,这一步操作的是让这个我们创建的节点的下一个连到我们找到的节点的下一个
ptemp->pnext = pt->pnext;
//后断
//再让我们找到的节点的下一个连上我们创建的节点
pt->pnext = ptemp;
}
}
int main(void)
{
head;
int a[10] = {
1,2,3,4,5,6,7,8,9,10};
for (int i = 0; i < 10; i++)
{
add(a[i]);
}
//ScanList();
/*struct node* find = selectnode(9);
if (find != NULL)
{
printf("%d\n", find->a);
}
else
{
printf("没找到");
}*/
//注意这个添加的时候,如果出现重复的数字,那么添加的时候只会出现第一个数字的位置
//如果想要改变的话,那么就要加一点循环加一点判断
AddListRand(2,45);
ScanList();
system("pause");
return 0;
}
注意这个算法最后一个链表的pnext是NULL,是不能够操作的,这个是个非法的地址,我们是没有权限去操作的,NULL也叫做空指针,一定要给指针初始化,如果没有初始化,那么指针乱指的话,说不定就会知道某个程序的地址,我们后面赋值的话就会报错了,所以不要乱指,不用的时候一定要赋值成NULL
不懂得可以问我,直接再下面评论,如果有更好得解决方案,也可以跟我说,我这个代码上面得链表操作还没有写完,其他得链表操作会进一步更新
有其他得问题也可以问我,我尽力帮你们解决,上面地代码可以直接就粘贴运行了,如果大家绝对可以的,记得关注我一手,持续更新