双链表
还是先说一下,在程序设计语言中的双链表的概念。
继单链表之后,我们在来说一说另外的一种链表方式,双链表。
在内存的表现结构上,还是分成下面的两种方式:
1,就是连续的内存结构。
2,就是跳转的内存结构。
在程序设计中,连续的内存结构,就是数组。
跳转的数据结构包括很多,链表只是其中的一种表现方式。上一次已经把数组和单链表的内存结构图,画出来了,那么我们在来看看在
内存中,双链表的表现方式又是什么样的呢?
在看完以上的,内存结构图后,如果对双链表还是没有一个直观的感受的话,那么你就听听我说的这个故事吧,也许会给你不一样的启发。
话说,有这样一只队伍,队员有女性也有男性,队伍有着统一的着装(就是定义的双链表的结构),他们喜欢挑战极限。
有一次,他们需要经过一个悬崖峭壁,悬崖上面的只能通过一个人,每个人必须要背贴在悬崖上,慢慢的往前走才能通过,
这个时候,队长发话了,所有队员一致排开,“不能手牵手” “不能手牵手” “不能手牵手”,重要的事情说三遍,只能抓住
前一个人的腰带或者后一个人的腰带,才可以。于是乎每一个队员都按照要求,把队伍排好了,他们就开始出发过悬崖了。
想像一下这样的场景是不是,和我们内存的结构图很像。
至于为什么不能手牵手,我想是因为,队长可能害怕刚进队伍的同志,心里防线比较弱,会手心出汗,导致抓的不牢固,会带来危险。
那么好了再理解了这样的数据结构后,我们要怎么操作这样的数据结构呢?
我们还是先从取值开始演示:
class DoubleNodeList {
int value;
public DoubleNodeList(int val) {
value = val;
}
DoubleNodeList next;
DoubleNodeList last;
}
class Main {
// 实现双列表逆序
private static DoubleNodeList doubleNodeListRevert(DoubleNodeList head) {
DoubleNodeList pre = null;
DoubleNodeList next;
while (head != null) {
next = head.next;
head.next = pre;
head.last = next;
pre = head;
head = next;
}
return pre;
}
// 拼接两个有序链表
private static NodeList sortNodeListSum(NodeList head1, NodeList head2) {
//边界值判断,如果有一个链表是空的那么就返回
if (head1 == null || head2 == null) {
return head1 == null ? head2 : head1;
}
// 1,先找头,谁小谁当头,这个头一旦找到就不变到最后返回的还是这个头
NodeList head = head1.value <= head2.value ? head1 : head2;
// 2,找到头的下一个节点
NodeList cur1 = head.next;
NodeList cur2 = head == head1 ? head2 : head1;
// 需要记录一个移动指针
NodeList pre = head;
while (cur1 != null && cur2 != null) {
if (cur1.value <= cur2.value) {
pre.next = cur1; // 如果链接的是当前连上的,那么 cur1 向下走一个
cur1 = cur1.next;
} else {
pre.next = cur2; // 如果链接的是第二条链上的,那么 cur2 向下走一个
cur2 = cur2.next;
}
pre = pre.next;
}
// 有可能一个短一个长
pre.next = cur1 == null ? cur2 : cur1;
return head;
}
public static void main(String[] args) {
DoubleNodeList doubleNodeList = new DoubleNodeList(1);
doubleNodeList.last = null;
DoubleNodeList doubleNodeList2 = new DoubleNodeList(2);
doubleNodeList.next = doubleNodeList2;
doubleNodeList2.last = doubleNodeList;
doubleNodeList2.next = null;
while (doubleNodeList != null) {
System.out.println(doubleNodeList.value);
doubleNodeList = doubleNodeList.next;
}
}
}
上面的代码是有关,双链表的基本操作。关于双链表和单链表的操作,远比止于此。目前的话先掌握一些基本的,基础好了,在往上盖的话,会相对于容易些。如果文章中出现了错误,或者是描述不正确的地方,请大家积极指出来,一起学习一起进步。