ListNode地址关系

本文详细探讨了链表中的地址保持现象,如何通过理解ListNode的结构和内存原理,实现节点值修改而不影响原链表。重点讲解了链表操作中常见的陷阱及正确删除节点的方法,适合前端和后端开发者理解链式数据结构的复杂性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ListNode表示一个链表结构,自定义的ListNode类如下:

public class ListNode {
 *     int val;
 *     ListNode next;
       //无参构造
 *     ListNode() {} 
       //带参构造           
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }

 一个基本的链表如下图所示,这个链表有两个参数,val为该节点的数值,next为该节点指向的另一个链表,即next为链表对象,尾节点的next为null。

在链表中需要注意的是:使用list = list.next语句时,当前链表地址已经发生改变。例如我们创建上图链表,并创建ListNodel2与l1地址相同:当l1=l1.next执行时,l1地址与l2已经不同,但是当执行l1.val = 1时,l2也会变化。

//创建1→2→3链表
ListNode l1 = new ListNode(1);
l1.next = new ListNode(2);
l1.next.next = new ListNode(3);
//创建l2地址与l1相同
ListNode l2 = l1;
l1 = l1.next;
l1.val = 1;
System.out.println(l2.next.val);

这是因为,listNode是指向头节点的地址值, 虽然l1进入下一节点,地址值发生改变,但链表指向顺序没变,l2指向了l1新的地址。因此在进行删除某一结点操作时,可以先创建新的链表保存头节点地址,再对原链表进行操作,这样,返回的新链表就保存了对原链表的修改。

 

 

本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中奇数值的结点重新组成一个新的链表链表结点定义如下: struct ListNode { int data; ListNode *next; }; 函数接口定义: struct ListNode *readlist(); struct ListNode *getodd( struct ListNode **L );函数readlist从标准输入读入一系列正整数,按照读入顺序建立单链表。当读到−1时表示输入结束,函数应返回指向单链表头结点的指针。 函数getodd将单链表L中奇数值的结点分离出来,重新组成一个新的链表。返回指向新链表头结点的指针,同时将L中存储的地址改为删除了奇数值结点后的链表的头结点地址(所以要传入L的指针)。 裁判测试程序样例: #include <stdio.h> #include <stdlib.h> struct ListNode { int data; struct ListNode *next; }; struct ListNode *readlist(); struct ListNode *getodd( struct ListNode **L ); void printlist( struct ListNode *L ) { struct ListNode *p = L; while (p) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { struct ListNode *L, *Odd; L = readlist(); Odd = getodd(&L); printlist(Odd); printlist(L); return 0; } /* 你的代码将被嵌在这里 */输入样例: 1 2 2 3 4 5 6 7 -1 输出样例: 1 3 5 7 2 2 4 6 下面代码有什么问题struct ListNode *readlist() { int n; struct ListNode *h=NULL,*t,*p; while(1) { scanf("%d",&n); if(n==-1) break; p=(struct ListNode *)malloc(sizeof(struct ListNode)); p->next=NULL; p->data=n; if(h==NULL) { h=p; t=p; } else { t->next=p; t=p; } } return h; }
03-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值