zoukankan      html  css  js  c++  java
  • 写了一个单链表的代码,而且支持反转链表,分组反转链表

    我的个人博客: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 }

    运行效果:

  • 相关阅读:
    C++常见错误大全(转)
    在字符串中删除特定字符
    C++ const 的全面总结
    函数返回局部变量问题
    TerminateThread()结束一个线程会有什么结果?
    小刘同学的第五十五篇博文
    小刘同学的五十、五一、五二博文断更…
    小刘同学的第五十三篇博文
    小刘同学的第四十九篇博文
    小刘同学的第四十八篇博文
  • 原文地址:https://www.cnblogs.com/wuyizuokan/p/11930362.html
Copyright © 2011-2022 走看看