链表下的查改 增删
一丶确定的链表下的操作
无论是静态创建 还是动态创建,当创建完成后都相当于 静态链表。
静态链表 下 目标点前后添加,删除都是站在 已经创建好的链表层面说的。
adddatafront(按照自己的意愿位置在已经确定的链表中添加)
insertFromhead头插法 / insertFromtail尾插法(也可以添加,但位置固定,只能在头处/尾处添加 小尾巴儿)
1.链表的打印
1.链表遍历的图解
2.链表遍历的文字解释
head是链表的头,固定不动。
point 相当于索引,有时候也相当于当下的节点,具有一直向后面移动的特性。
point->next 相当于下一个节点(下一个节点的地址),当前节点内的地址存储区。
3.point = point->next的文字解释
左边相当于地址变量,用于存放下个节点的地址;
右边是地址,相当于来到了下个节点的面前。
point是索引,point->是下一个节点
4.链表打印的代码
printdata(struct Test *head)
{
struct Test *point = head;
while(point != NULL){
printf("%d\n",point->data);
point = point->next;
}
return 0;
}
2.链表的节点增加 (“静态链表”下都是添加的一个新节点,代码实现都是添加一个new节点)
两个节点相连的解释:
两个节点相连相当于 前面的节点(的地址存储区)存放者下一个节点的地址。
“目标”的前面 增加节点A
case 0 :A作为头节
case 1:A作为非头结点
图表解释:
文字解释:
注意: 在结尾前面插入 point1满足while条件后,
进入循环体在其中通过条件改变成point2,
即当point2进入while()判断时不满足条件
分解为 判断目标 和插入节点
1.判断目标
if (point->data == data) 该行代码对应①
if(point->next-data ==data) 该行代码对应②
2.插入节点
new->next = head; 该段对应①
return new;
00000000000000000000000
new->next = point-next; 该段对应②
point->next = new;
return head;
目标前插入节点有两种情况:①和②
①:改变了链表的头。
②:未改变链表头。
在目标前面插入新节点的代码
struct Test * adddatafront(struct Test* head,int data, struct Test *new)
{
struct Test* point = head;
if(point->data == data) //最大的区别①和② 是遍历条件的不用
{
new->next = head;
return new;
}
while (point->next != NULL)
{
if(point ->next-data == data)
{
new->next = piont->next; //此时在当当前节点 仍然开始是point
point->next = new;
return head;
}
point = point->next;
}
}
“目标”的后面 增加节点
图解:
文解:
while遍历的条件:while(point!= NULL)
头的后面 加入;
尾的后面 加入;
中间的后面加入;
以上三种情况都是一个算法逻辑。
在目标后面插入新节点的代码:
struct Test * adddatabehand (struct Test* head,int data,struct Test* new)
{
struct Test * point = head;
while(point != NULL){
if(point->data == data){
new->next = point->next;
point->next = new;
return head;
}
point = point->next;
}
return head;
}
总结:2在前面加 与 在后面加 遍历条件上的区别
在目标前加入一个新节点 和在目标后加入方法类似
但若新节点作为头结点和非头节点会影响链表
目标前 if(point->data == data) while(point ->next != NULL)
而目标后 while(point!= NULL)
区别000000: 在尾部后添加,point直接在尾部;
在尾部前添加,A C(最后两个),point最先来到A处,然后才会来到尾部C处;
3.链表的节点删除
if 删除的是头结点
if 删除的是非头结点
删除节点 与在目标前添加新节点的思路都是相同的。先判断头节点思考一波,再在AC(最后两个节点)思考一波。
删除节点的代码:
静态链表下的删除
struct Test * deletedata(struct Test *head,int data)
{
struct Test *point =head;
if(point->data == data) {
head = head->next;
return head;
}
while(point->next !=NULL){
if(point->next->data == data){
point->next=point->next->next;
return head;
}
point = point->next;
}
}
动态链表下的删除
struct Test * deletedata( struct Test *head,int data )
{
struct Test *point = head;
if(point->data == data){
head= head->next;
free(point);
return head;
}
while(point->next != NULL){
if(point->next->data == data){
struct Test*tmp = point->next; //可能这有点错误 应该是struct Test*tmp = piont;
point->next = point->next->next;
free(tmp) ;
return head;
}
point = point->next;
}
return head;
}
}
二丶链表创建的方法
静态创建
静态创建链表的代码
struct Test
{
int data;
struct Test* next;
};
struct Test t1;
struct Test t2;
struct Test t3;
t1 = {1,NULL};
t2 = {2.,NULL};
t3 = {3,NULL};
t4 = {4,NULL};
t1.next = &t2;
t2.next= &t3;
t3.next= &t4;
动态创建
1.createLink(就是创建new节点,先不管head是否为NULL)
核心:创建new,并让用户赋值。不断创建,0是退出标志
代码实现
struct Test * createLink(struct Test *head)
{
struct Test *new ;
while(1){ //只有在输入0才能退出while循环 同时退出了createLink函数
new = (struct Test*) malloc ( sizeof( struct Test ) );
printf("请输入新节点的内容");
scanf("%d",& ( new->data )); //注意取地址
if(new->data == 0){
free(new);
printf("0 quit");
return head;
}
head= insertFromhead(head,new);
}
}
2.使用insertFromhead头插法 / insertFromtail尾插法(若head为空 则把new给head)
insertFromhead头插法 (只需在head前面加入new即可!)
核心:找到头
struct Test* insertFromhead(struct Test *head,struct Test *new) //需要判断head是否为NULL
{
struct Test* point = head;
if(point == NULL){
head= new;
}else{
new->next=point; //因为是头插法,本身就是总是首先拿到的是head所以根本不用像尾节点那样 遍历
head= new; //不用找到尾节点,直接在头节点head前面增加就可以。
}
return head;
}
insertFromtail尾插法 (需要通过while遍历到尾巴节点,然后才能在尾巴节点后加入new!)
核心:找到尾
struct Test* insertFromtail(struct Test *head,struct Test *new) //需要判断head是否为NULL
{
struct Test* point = head;
if(point == NULL){
head= new;
return head;
}
while(point->next != NULL){ //上面的头插法是用else语句实现的而这里使用while里的条件实现的。
point = point->next; //与头插法不同的是,尾插法的最大特征是 把piont移到(A,B,C,NULL)C处。
}
point->next = new;
return head;
}
动态链表创建完成后 加入小尾巴
头插法小尾巴
通过createLink已经创建好链表。
即链表已确定 然后在链表头的位置前面 加入小尾巴儿9999
直接调用insertFromhead函数
struct Test new1;
new1.data = 9999;
new1.next = NULL;
head = insertFromhead(head,&new1) ;
尾插法小尾巴
通过createLink已经创建好链表。
即链表已确定 然后在链表尾的位置后面 加入小尾巴儿6666
直接调用 insertFromtail函数
struct Test new2;
new2.data = 6666;
new2.next = NULL;
head = insertFromtail(head,&new2) ;