此处定义单链表的数据结构与LeetCode上相同,为:
public class ListNode
{
public int val;
public ListNode next;
public ListNode(int x)
{
val =x;
}
}
首先来看几个:
例子1
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
ListNode headA = head;
ListNode headB = head;
headA.val= 5
Console.WriteLine(head.val);
输出是 5
例子2
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
ListNode headA = head;
ListNode headB = head;
headA.next = new ListNode(5);
Console.WriteLine(head.val);
输出是 1
例子3
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
ListNode headA = head;
ListNode headB = head;
unsafe
{
fixed(int* hp = &head.val)
{
Console.WriteLine((int)hp);
}
fixed(int* hpA = &headA.val)
{
Console.WriteLine((int)hpA);
}
fixed(int* hpB = &headB.val)
{
Console.WriteLine((int)hpB);
}
}
输出的地址相同,分别是:
34677688
34677688
34677688
例子4
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
ListNode headA = head;
ListNode headB = head;
//head的地址
GCHandle h = GCHandle.Alloc(head, GCHandleType.WeakTrackResurrection);
IntPtr addr = GCHandle.ToIntPtr(h);
Console.WriteLine("0x" + addr.ToString("X"));
//headA的地址
GCHandle hA = GCHandle.Alloc(headA, GCHandleType.WeakTrackResurrection);
IntPtr addrA = GCHandle.ToIntPtr(hA);
Console.WriteLine("0x" + addrA.ToString("X"));
//headB的地址
GCHandle hB = GCHandle.Alloc(headB, GCHandleType.WeakTrackResurrection);
IntPtr addrB = GCHandle.ToIntPtr(hB);
Console.WriteLine("0x" + addrB.ToString("X"));
Console.ReadLine();
输出的地址不同,分别是:
0x4110F8
0x4110F4
0x4110F0
由以上4个例子,我们可以得出链表的数据结构:
headA = head
表示headA
中的值类型val
指向了head
的值类型val
,地址相同,headA
中的引用next
复制了head
的next
,地址不同,总体来看, headA
和head
在堆上是不同的地址。
例子5
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
ListNode headA = head;
ListNode headB = head;
headA.next.next = null;
Console.WriteLine(head.next.next.val);
输出报错,提示head.next.next
为空指针。