1,链表静态创建
链表是一个由 节点组成的集合。这里的每一个节点都是一个结构体 。链表里面 节点与节点之间的内存空间是不一定连续的,很大概率是分散的。
为了构成我们想要的链表,我们需要在 结构体里面 声明一个结构体指针。这个结构体指针,用来保存下一个节点的地址。以此类推,我们就可以得到我们想要得链表了。下面我将用几何图形来表示链表,这样或许就更好理解些许了。
首先我们先定义一个结构体。
#include<stdio.h>
struct Text
{
int num;
struct Text* next;
};
这个结构体里面有两种 属性 一个是整型 一个是结构体指针。
这里记住,结构体 就是链表 里面的节点。每一个节点 都有一个结构体指针,要想让单独的结构体,变成我们想要的链表就要让结构体之间产生联系。为了让节点与节点之间产生联系,我们需要定义一个结构体指针。这个结构体指针用来保存 我们下一个结构体的地址。当我们想要访问下一个节点时,我们只需要访问结构体指针来访问下一个节点。
p;
p->next = p->next->next; //
p = p->next;//是指针偏移。
以下就是 创建 静态链表的方式。
#include<stdio.h>
struct Text
{
int num;
struct Text* next;
};
int main()
{
struct Text t1 = {1,NULL};
struct Text t2 = {2,NULL};
struct Text t3 = {3,NULL};
struct Text t4 = {4,NULL};
struct Text t5 = {5,NULL};
struct Text t6 = {6,NULL};
struct Text new = {1001,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
//以上是静态链表的创建
//以下是 链表的一些 输出 增删改查 的操作
int data2;
struct Text *hand = &t1;
struct Text *hande = NULL;
printLink(hand);
//hande = addLink2(hand,&new,2);
//printLink(hande);
hande = delete(hand,2);
printLink(hande);
seachLink(hand,4);
hande = gaiLink(hand,5,10086);
printLink(hande);
//printf("%d ",data2);
return 0;
}
2,增 增加节点
想要往链表插入一个节点 确定要在哪个节点的前面或者后面插入节点。 头插法,尾插法
头插法 1,在链表头的前面插入 节点。
就是用一个新的节点的next 来保存 头节点的地址,然后让这个新的节点成为这个链表 的链表头,以下是代码
//p-> == data new->next = hand ;
//hand = new ; return hand;
if(p->num == data){
new->next = hand;
hand = new;
return hand;
}
2, 在不是链表头的节点的 前面插入节点。
注意的是 判断条件
//头插法
struct Text* addLink(struct Text*hand,struct Text*new,int data)
{
struct Text*p = hand;
if(p->num == data){
new->next = hand;
hand = new;
return hand;
}
//循环 当p->next为NULL的时候就跳出循环
while(p->next!=NULL)
{
if(p->next->num == data){ //如果p的下一个节点 的值 等于data 就将新的节点先与 p 先前连接的节点进行连接
//然后将new 的地址保存到p->next.
new->next = p->next;
p->next = new;
return hand; //返回
}
p = p->next;
}
}
尾插法
就是判断 p !=NULL 如果是 就继续循环,然后p = p->next 进行指针的偏移。
以下是代码的实现
/尾插法
struct Text* addLink2(struct Text*hand ,struct Text*new,int data)
{
struct Text*p = hand; //定义的临时变量
while(p!=NULL) // 判断P地址是否为空 ,为空就跳出循环。
{
if(p->num == data)
{
new->next = p->next;
p->next = new;
return hand;
}
p = p->next;
}
}
3,删除节点
1,删除节点 就是将现在的节点p->next 保存的地址 换成 p->next->next就行了,这样就可以把p 往后一个节点删除了。
以下是代码实现。
//删除
struct Text* delete(struct Text*hand,int data)
{
struct Text*p = hand;
if(p->num == data) //头节点的删除
{
p = p->next;
hand = p;
return hand;
}
while(p ->next!= NULL) //非头节点的删除方式
{
if(p->num == data)
{
p->next = p->next->next;
return hand;
}
p = p->next;
}
}
4,改变 节点里面的数据
改变节点的数据,就是从新给一个data1 把原来的 data换掉
以下是代码实现
//改正
struct Text* gaiLink(struct Text*hand,int data,int data2)
{
struct Text*p = hand;
while(p!=NULL) //遍历链表
{
if(p->num == data) // 找到 要改变的数据
{
p->num = data2; //更改数据
return hand; //返回 链表头地址
}
p = p->next; //指针偏移
}
printf("没有此数据\n");
return hand;
}
5,查看节点
也是先遍历链表 然后找到我们要查看的数据 然后 输出我们要查看的数据
//查看
void seachLink(struct Text*hand ,int data)
{
struct Text*p = hand;
while(p->next !=NULL)
{
if(p->num == data)
{
printf("%d \n",p->num);
}
p = p->next;
}
}
6,打印,输出链表
先遍历链表 然后输出节点的数据 这里要用到指针偏移。
void printLink(struct Text*hand)
{
struct Text*p = hand;
while(p != NULL)
{
printf("%d ",p->num); //不偏移 会一直循环,一直打1;
p = p->next; //这是要进行偏移,直到P ==NULL 才能跳出循环
}
printf("\n");
}
7,整段代码的实现
通过封装函数 将功能分类 虽然函数的封装 会降低些许性能 但是 提升了可读性 改代码的便捷。
#include<stdio.h>
struct Text
{
int num;
struct Text* next;
};
//静态插入链表
//头插法
struct Text* addLink(struct Text*hand,struct Text*new,int data)
{
struct Text*p = hand;
if(p->num == data){
new->next = hand;
hand = new;
return hand;
}
while(p->next!=NULL)
{
if(p->next->num == data){
new->next = p->next;
p->next = new;
return hand; //返回
}
p = p->next;
}
}
//尾插法
struct Text* addLink2(struct Text*hand ,struct Text*new,int data)
{
struct Text*p = hand;
while(p !=NULL)
{
if(p->num == data)
{
new->next = p->next;
p->next = new;
return hand;
}
p = p->next;
}
}
//删除
struct Text* delete(struct Text*hand,int data)
{
struct Text*p = hand;
if(p->num == data)
{
p = p->next;
hand = p;
return hand;
}
while(p ->next!= NULL)
{
if(p->num == data)
{
p->next = p->next->next;
return hand;
}
p = p->next;
}
}
//查看
void seachLink(struct Text*hand ,int data)
{
struct Text*p = hand;
while(p->next !=NULL)
{
if(p->num == data)
{
printf("%d \n",p->num);
}
p = p->next;
}
}
//改正
struct Text* gaiLink(struct Text*hand,int data,int data2)
{
struct Text*p = hand;
while(p!=NULL)
{
if(p->num == data)
{
p->num = data2;
return hand;
}
p = p->next;
}
printf("没有此数据\n");
return hand;
}
void printLink(struct Text*hand)
{
struct Text*p = hand;
while(p != NULL)
{
printf("%d ",p->num); //不偏移 会一直循环,一直打1;
p = p->next; //这是要进行偏移,直到P ==NULL 才能跳出循环
}
printf("\n");
}
int main()
{
struct Text t1 = {1,NULL};
struct Text t2 = {2,NULL};
struct Text t3 = {3,NULL};
struct Text t4 = {4,NULL};
struct Text t5 = {5,NULL};
struct Text t6 = {6,NULL};
struct Text new = {1001,NULL};
t1.next = &t2;
t2.next = &t3;
t3.next = &t4;
t4.next = &t5;
t5.next = &t6;
int data2;
struct Text *hand = &t1;
struct Text *hande = NULL;
printLink(hand);
hande = addLink2(hand,&new,6);
printLink(hande);
hande = delete(hand,2);
printLink(hande);
seachLink(hand,4);
hande = gaiLink(hand,5,10086);
printLink(hande);
//printf("%d ",data2);
return 0;
}
文章结束,希望能带来收获