zoukankan      html  css  js  c++  java
  • 数据结构_单链表操作总结

      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 }
  • 相关阅读:
    Largest Rectangle in Histogram
    Valid Sudoku
    Set Matrix Zeroes
    Unique Paths
    Binary Tree Level Order Traversal II
    Binary Tree Level Order Traversal
    Path Sum II
    Path Sum
    Validate Binary Search Tree
    新手程序员 e
  • 原文地址:https://www.cnblogs.com/zzsaf/p/7054144.html
Copyright © 2011-2022 走看看