写了一个单链表的代码,而且支持反转链表,分组反转链表

我的个人博客:https://www.wuyizuokan.com

Node.java:

 1 package com.me.node;
 2 
 3 /**
 4  * 组成链表的结点对象
 5  * @author wuyizuokan
 6  *
 7  * @param <T>
 8  */
 9 public class Node<T> {
10     /*节点中存放的值*/
11     private T value;
12     /*下一个节点的引用*/
13     private Node<T> next;
14     
15     public T getValue() {
16         return value;
17     }
18     public void setValue(T value) {
19         this.value = value;
20     }
21     public Node<T> getNext() {
22         return next;
23     }
24     public void setNext(Node<T> next) {
25         this.next = next;
26     }
27 }

NodeList.java:

  1 package com.me.node;
  2 
  3 /**
  4  * 链表实现类
  5  * @author wuyizuokan
  6  *
  7  * @param <T>
  8  */
  9 public class NodeList<T> {
 10     
 11     /*链表头节点*/
 12     private Node<T> head;
 13     
 14     /**
 15      * 向链表添加元素
 16      * @param t
 17      */
 18     public void add(T t) {
 19         Node<T> node = new Node<T>();
 20         node.setValue(t);
 21         if (head == null) {
 22             head = node;
 23         } else {
 24             add(head, node);
 25         }
 26     }
 27     
 28     private void add(Node<T> node, Node<T> newNode) {
 29         if (node.getNext() == null) {
 30             node.setNext(newNode);
 31         } else {
 32             add(node.getNext(), newNode);
 33         }
 34     }
 35     
 36     /**
 37      * 根据分组反转链表
 38      * @param i
 39      */
 40     public void reverseGroup(int groupSize) {
 41         head = reverseGroup(head, groupSize);
 42     }
 43     
 44     private Node<T> reverseGroup(Node<T> node, int i) {
 45         // splitNode用于取数组的前i个元素,下面的for循环会让splitNode移动到第i个节点的位置
 46         Node<T> splitNode = node;
 47         for (int j = 1; j < i; j++) {
 48             if (splitNode != null) {
 49                 splitNode = splitNode.getNext();
 50             } else {
 51                 break;
 52             }
 53         }
 54         // 如果移动到第i个节点的位置后,节点为null,说明无法达到一组的大小,则反转后直接返回
 55         if (splitNode == null) {
 56             return reversList(node);
 57         }
 58         // 标记好剩下的链表头,用于下一批分组
 59         Node<T> nextListHead = splitNode.getNext();
 60         // 设置splitNode的下一个节点为null,是为了把第i个节点前的链表抽取出来。
 61         splitNode.setNext(null);
 62         // 调用反转链表的方法进行反转。
 63         Node<T> newHead = reversList(node);
 64         // 递归调用按组反转数组的方法
 65         Node<T> nextListHeadTmp = reverseGroup(nextListHead, i);
 66         // 把下一次返回的反转的子列表拼接到这一次后面。
 67         node.setNext(nextListHeadTmp);
 68         // 返回新列表的头节点。
 69         return newHead;
 70     }
 71     
 72     /**
 73      * 反转列表
 74      */
 75     public void reversList() {
 76         head = reversList(head);
 77     }
 78     
 79     private Node<T> reversList(Node<T> node) {
 80         // 这里作为递归的出口,相当于是用递归把链表按节点拆分,直到拆分到最后一个节点
 81         if (node == null || node.getNext() == null) {
 82             return node;
 83         }
 84         
 85         // 递归调用反转列表的方法,返回新列表的头部
 86         Node<T> result = reversList(node.getNext());
 87         // 因为是递归,这里的node实际上是从倒数第二个节点开始往前的每一个节点。需要把它的下一个
 88         // 节点的下一个节点指向它自己。
 89         node.getNext().setNext(node);
 90         // 把自己的下一个节点置空,实际上整个函数执行完了之后,除了之前的头节点的下一个节点引用会为空外,其他节点不会。
 91         node.setNext(null);
 92         return result;
 93     }
 94     
 95     public void showList() {
 96         System.out.print("[");
 97         if (head != null) {
 98             showNode(head);
 99         }
100         System.out.println("]");
101     }
102     
103     public void showNode(Node<T> node) {
104         if (node != null) {
105             System.out.print(node.getValue());
106             if (node.getNext() != null) {
107                 System.out.print(", ");
108                 showNode(node.getNext());
109             }
110         }
111     }
112 }

测试代码:

 1 package com.me.reverseLinkedList;
 2 
 3 import com.me.node.NodeList;
 4 
 5 public class Test {
 6     public static void main(String[] args) {
 7         NodeList<String> nodeList = new NodeList<String>();
 8         nodeList.showList();
 9         nodeList.add("a");
10         nodeList.add("b");
11         nodeList.add("c");
12         nodeList.add("d");
13         nodeList.add("e");
14         nodeList.add("f");
15         nodeList.add("g");
16         nodeList.add("h");
17         
18         nodeList.showList();
19         // 反转链表
20         nodeList.reversList();
21         nodeList.showList();
22         // 分组反转链表
23         nodeList.reverseGroup(3);
24         nodeList.showList();
25     }
26 }

运行效果:

 

posted @ 2019-11-25 20:44  微弦  阅读(354)  评论(0编辑  收藏  举报