链表的划分——按值划分为三个区域

题目:

根据值val将链表划分为小于val的左半区,等于val的中间半区,大于val的右半区

 

方法1:
将其转为node数组,用数组的思想将其实现(需额外空间,且实现还更复杂)

代码解析:

 1 public static void PartitionList1(MyLink list,int val) {
 2         Node p = list.head;
 3         //要先知道长度才知道给数组开多少空间
 4         int len = 0, cnt = 0;
 5         while (p != null) {
 6             len++;
 7             p = p.next;
 8         }
 9         Node[] arr = new Node[len];
10         //将链表节点内容复制到数组中
11         p = list.head;
12         while (p != null) {
13             arr[cnt++] = p;
14             p = p.next;
15         }
16         //对数组进行调整
17         int less = -1, more = arr.length;
18         int now = 0;
19         while (now < more) {
20             if (arr[now].num < val) {
21                 swap(arr,++less,now++);
22             }
23             else if (arr[now].num == val) {
24                 now++;
25             }
26             else {
27                 swap(arr,--more,now);
28             }
29         }
30         //将得到的数组内容返还给链表
31         list.head = arr[0];
32         p = list.head;
33         for (int i = 1; i < arr.length; i++) {
34             p.next = arr[i];
35             p = p.next;
36         }
37         p.next = null;
38     }

 

方法2:

将其分为小于等于大于三块链表型区域,用链表分别进行区域内部和区域之间连接

 1 public static void PartitionList2(MyLink list,int val) {
 2         Node sh = null, st = null;//小于部分的头尾指针
 3         Node eh = null, et = null;//等于部分的头尾指针
 4         Node bh = null, bt = null;//大于部分的头尾指针
 5         Node p = list.head;
 6         Node next = null;//用来存储下一个节点
 7         //先把三块分区域的链表组织好
 8         while (p != null) {
 9             next = p.next;//即在一次循环中同时获得了相邻的两个节点内容
10             p.next = null;//这个节点可以直接指向null(因为后面不再用它了)
11             if (p.num < val) {
12                 if (sh == null) {
13                     sh = p;
14                     st = p;//sh==null已经说明st==null
15                 }
16                 else {//要更新st
17                     st.next = p;
18                     st = st.next;
19                 }
20             }
21             else if (p.num == val) {
22                 if (eh == null) {
23                     eh = p;
24                     et = p;
25                 }
26                 else {
27                     et.next = p;
28                     et = et.next;
29                 }
30             }
31             else {
32                 if (bh == null) {
33                     bh = p;
34                     bt = p;
35                 }
36                 else {
37                     bt.next = p;
38                     bt = bt.next;
39                 }
40             }
41             p = next;
42         }
43         if (st != null) {//如果有小于区域(没有小于区域就不用考虑小于到等于的连接 )
44             st.next = eh;//先不管eh是不是null,在下一步处理
45             et = et == null ? st : et;//找谁做连接到大于区域的头(如果et为空就用st)
46         }
47         if (et != null) {//如果有小于或者等于的区域(此时等于同时考虑了两个区域是否至少存在一个)
48                          //则需要将其连到大于区域(不关心大于区域是否为空)
49             et.next = bh;
50         }
51         //找到最前面那个不为空的头即可
52         list.head = sh != null ? sh : (eh != null) ? eh : bh;
53     }

 

posted @ 2022-04-09 16:34  jue1e0  阅读(89)  评论(0)    收藏  举报