• 数据结构_单链表操作总结


      1 package zz;
      2 
      3 import java.util.Stack;
      4 
      5 /**
      6  * 
      7  * @author zz
      8  * 关于java中链表的操作
      9  * 0. 向链表中插入新节点
     10  * 1. 求单链表中结点的个数: getListLength 
     11  * 2. 将单链表反转: reverseList(遍历),reverseListRec(递归) 
     12  * 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode 
     13  * 4. 查找单链表的中间结点: getMiddleNode 
     14  * 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归) 
     15  * 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec 
     16  * 7. 对链表的后半部分进行反转。reversePartNode
     17  * 8. 判断单链表是否存在环,isLoop。 使用两个指针,fast和low,fast一次走两步,low一次走一步。若存在环,总会有某个时刻fast和low指向同一节点
     18  * 9. 求出环的长度。getLoopLength().记录8中fast和low的遭遇点。然后让low走一圈环记数即可
     19  * 10. 对单链表进行排序,listSort(归并),insertionSortList(插入)
     20  * // 注释部分代码也经过调试正确
     21  */
     22 public class LinkedListSummary {
     23     public static class Node {
     24         int data;
     25         Node next;
     26         public Node(int value) {
     27             data = value;
     28             next = null;
     29         }
     30     }
     31     //向链表中插入新节点
     32     public static void addNode(Node head, int data) {
     33         Node newNode = new Node(data);
     34         if(head == null) {
     35             head = newNode;
     36             return;
     37         } else {
     38             Node temp = head;
     39             while(temp.next != null) {
     40                 temp = temp.next;
     41             }
     42             temp.next = newNode;            
     43         }
     44     }
     45     //输出链表的长度
     46     public static int getListLength(Node head) {
     47         int len = 0;
     48         //if(head == null) return 0;
     49         Node temp = head;
     50         while(temp != null) {
     51             len++;
     52             temp = temp.next;
     53         }
     54         System.out.println("输出链表长度:" + len);
     55         return len;
     56     }    
     57     //顺序打印链表数据 
     58     public static void print(Node head) {
     59        if(head == null) {
     60            System.out.println("链表为空");
     61            return;
     62        }
     63        Node temp = head;
     64        while(temp != null) {
     65            System.out.print(temp.data + " ");
     66            temp = temp.next;
     67        }
     68     }
     69     //方法1:使用栈反向遍历单链表
     70     public static void reversePrint(Node head) {
     71         if(head == null || head.next == null) return;
     72         Stack<Node> nodes = new Stack<Node>();
     73         Node temp = head;
     74         while(temp != null) {
     75             nodes.push(temp);
     76             temp = temp.next;
     77         }
     78         while(!nodes.isEmpty()) {
     79             //nodes.pop();
     80             System.out.print(nodes.pop().data + " ");
     81         }
     82     }
     83     //方法二:反向遍历单链表
     84     public static Node reversePrint2(Node head) {
     85         if(head == null || head.next == null) return head;
     86         Node pre = null;
     87         Node temp = null;
     88         while(head != null) {
     89             temp = head.next;
     90             head.next = pre;
     91             pre = head;
     92             head = temp;
     93         } 
     94         print(pre);
     95     //    System.out.println(head == null ? "空" : "非空");
     96         return pre;
     97     }    
     98     //递归反向遍历单链表
     99     public static Node reversePrintRec(Node head) {
    100         if(head == null || head.next == null) {
    101             System.out.println("链表遍历完成,只有head节点或为空链表");
    102             return head;
    103         }
    104         Node reHead = reversePrintRec(head.next);
    105          head.next.next = head;
    106         head.next = null;
    107         return head;
    108     }
    109     //从尾到头打印递归打印单链表
    110     public static void reversePrintListRec(Node head) {
    111         if(head == null) {
    112             return;
    113         } else {
    114             reversePrintListRec(head.next);
    115             System.out.print(head.data + ",");
    116         }
    117     }
    118     //查找单链表的倒数第K个节点(k>0)
    119     public static Node reGetKthNode(Node head, int k) {
    120         int len = 0;
    121         Node temp = head;
    122         while(temp != null) {
    123             len++;
    124             temp = temp.next;
    125         }
    126         if(k > len) {
    127             System.out.println("链表长度有限,小于K,找不到倒数第K个节点");
    128             return null;
    129         }
    130         Node n1 = head;
    131         Node n2 = head;
    132         for(int i = 0; i < k; i++) {
    133             n1 = n1.next;
    134         }
    135         while(n1 != null){
    136             n2 = n2.next;
    137             n1 = n1.next;
    138         }
    139         System.out.println(n2.data);
    140         return n2;
    141     }
    142     //查找单链表的中间结点: getMiddleNode
    143     public static Node getMiddleNode(Node head) {
    144         if(head == null || head.next == null) return head;
    145         Node n1 = head;
    146         Node n2 = head;
    147         while(n2 != null && n2.next != null) {
    148             n1 = n1.next;
    149             n2 = n2.next.next;
    150         }
    151         //System.out.println(n1.data);
    152         return n1;
    153     }
    154     //已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList
    155     public static Node mergeSortedList(Node head1, Node head2) {
    156         if(head1 == null) return head2;
    157         if(head2 == null) return head1;
    158         Node target = null;
    159         if(head1.data > head2.data) {
    160             target = head2;
    161             head2 = head2.next;
    162         } else {
    163             target = head1;
    164             head1 = head1.next;
    165         } 
    166         target.next = null;
    167         Node newHead = target;
    168         while(head1 != null && head2 != null) {
    169             if(head1.data > head2.data) {
    170                 target.next = head2;
    171                 head2 = head2.next;
    172             } else {
    173                 target.next = head1;
    174                 head1 = head1.next;
    175             }
    176             target = target.next;
    177             target.next = null;
    178         }
    179         if(head1 == null) {
    180             target.next = head2;
    181         } else {
    182             target.next = head1; 
    183         }
    184         return newHead;
    185     }
    186     //已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序(递归实现): mergeSortedListRec
    187     public static Node mergeSortedListRec(Node head1, Node head2) {
    188         if(head1 == null) return head2;
    189         if(head2 == null) return head1;
    190         Node head = null;
    191         if(head1.data > head2.data) {
    192             head = head2;
    193             head.next = mergeSortedListRec(head2.next, head1);
    194         } else {
    195             head = head1;
    196             head.next = mergeSortedListRec(head1.next, head2);
    197         }
    198          return head;
    199     }
    200     //将链表的后半部分进行反转
    201     public static Node reversePartNode(Node head){  
    202         Node flag = head;
    203         Node cur = null;
    204         Node mid = getMiddleNode(head);
    205         
    206         while(flag.next != mid) {     //取出中间节点的 前一个节点并保存
    207             flag = flag.next;
    208         }
    209         Node pre = null;
    210         //System.out.println("----" + flag.data);
    211         while(mid != null) {
    212             cur = mid.next;
    213             mid.next = pre; 
    214             pre = mid;
    215             mid = cur;
    216         } 
    217        
    218         flag.next = pre;
    219         print(head);
    220 
    221         return head;
    222     }  
    223     //判断链表是否存在环
    224     public static boolean isLoop(Node head) {
    225         if(head == null || head.next != null) return false;
    226         Node fast = head;
    227         Node low = head;
    228         while(fast != null && fast.next != null) {
    229             low = low.next;
    230             fast = fast.next.next;
    231             if(fast == low) break;
    232         }
    233         if(fast == null || fast.next == null) return false;
    234         return true;
    235     }
    236     //求出环的长度
    237     public static int getLoopLength(Node head) {
    238         if(head == null || head.next != null) return 0;
    239         Node fast = head;
    240         Node low = head;
    241         while(fast != null && fast.next != null) {
    242             low = low.next;
    243             fast = fast.next.next;
    244             if(fast == low) break;
    245         }
    246         if(fast == null || fast.next == null) return 0;
    247         else {
    248             int loopLen = 1;
    249             while(low.next != fast) {
    250                 loopLen++;
    251                 low = low.next;
    252             }
    253             return loopLen;
    254         }
    255         
    256     }
    257 /*  
    258     //单链表排序
    259     public static Node listSort(Node head) {
    260         Node nex = null;
    261         if(head == null || head.next == null) return head;
    262         else if(head.next.next == null) {
    263             nex = head.next;
    264             head.next = null;
    265         } else {
    266             Node mid = getMiddleNode(head);
    267             nex = mid.next;
    268             mid.next = null;
    269         }
    270         print(mergeSortedList(listSort(head), listSort(nex)));
    271         return mergeSortedList(listSort(head), listSort(nex));
    272     }
    273 */
    274     public static void main(String[] args) {
    275         Node head = new Node(0);
    276         addNode(head, 6);
    277         addNode(head, 2);
    278         addNode(head, 1);
    279         addNode(head, 4);
    280         addNode(head, 3);
    281         addNode(head, 5);
    282     //    listSort(head);
    283         System.out.println("顺序打印链表数据:");
    284         print(head);
    285         System.out.println();
    286         System.out.println("反转单链表后半部分节点:");
    287         reversePartNode(head);
    288         System.out.println();
    289         
    290         if(isLoop(head)) {
    291             System.out.println("存在环");
    292         } else System.out.println("不存在环");
    293         
    294         Node head1 = new Node(10);
    295         addNode(head1, 11);
    296         addNode(head1, 12);
    297         addNode(head1, 13);
    298         addNode(head1, 14);
    299         addNode(head1, 15);
    300         addNode(head1, 16);
    301         addNode(head1, 17);
    302         addNode(head1, 18);
    303         addNode(head1, 19);
    304         addNode(head1, 20);
    305         /*
    306         System.out.println();
    307         System.out.println("反转单链表后半部分节点:");
    308         reversePartNode(head1);
    309         System.out.println();
    310         */
    311         Node head2 = new Node(100);
    312         for(int i = 0; i < 8; i++) {
    313             addNode(head2, 100+i);
    314         }
    315         
    316         Node head3 = new Node(1000);
    317         for(int i = 0; i < 8; i++) {
    318             addNode(head3, 1001+i);
    319         }
    320         
    321         getListLength(head);
    322         System.out.println("顺序打印链表数据:");
    323         print(head);
    324     /*
    325     //    System.out.println();
    326     //    System.out.println("使用栈反转链表:");
    327     //    reversePrint(head);
    328     //    System.out.println();
    329     //    reversePrint2(head);
    330     //    System.out.println();
    331     //    System.out.println("递归反向遍历单链表");
    332     //    System.out.println("----" + head.data);
    333     //    reversePrintListRec(head);
    334     //    System.out.println();
    335     //    System.out.println("查找单链表的倒数第K个节点的值");
    336     //    reGetKthNode(head, 3);
    337     //    System.out.println();
    338     //    System.out.println("查找单链表的中间节点的值");
    339     //    getMiddleNode(head);
    340     //    System.out.println();
    341     //    System.out.println("合并两个单链表:");
    342     //    Node mergeHead = mergeSortedList(head, head1);
    343     //    print(mergeHead);
    344     //    System.out.println();
    345     //    System.out.println("递归实现合并两个单链表:");
    346     //    Node mergeHeadRec = mergeSortedListRec(head2, head3);
    347     //    print(mergeHeadRec);
    348         */
    349     } 
    350 }
  • 相关阅读:
    Object上的静态方法
    【php实现数据结构】单向链表
    图片上传方案详解
    新手必踩坑之display: inline-block
    前端算法题:找出数组中第k大的数字出现多少次
    this的五种指法
    通过java反射实现的excel数据导出
    算法系列-动态规划(4):买卖股票的最佳时机
    算法系列-动态规划(3):找零钱、走方格问题
    数据库仓库系列:(一)什么是数据仓库,为什么要数据仓库
  • 原文地址:https://www.cnblogs.com/zzsaf/p/7054144.html
Copyright © 2020-2023  润新知