4.单向链表的常见题型
Posted quxiangxiangtiange
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4.单向链表的常见题型相关的知识,希望对你有一定的参考价值。
本篇主要是单向链表题型的实战,比如反转单向链表、查找单向链表的中间节点、判断一个链表是否有环、合并两个有序链表、判断一个单向链表是否是回文链表。
/** * Node为链表结点对象 */ class Node { public Integer data; public Node next; public Node(Integer data){ this.data = data; } } public class LinkedListUtil { /** * 反转一个单向链表 * 思路:申请两个变量(指针)pre、cur,pre指向null,cur指向头结点,cur充当临时变量保存着当前操作结点的下一结点 * @param head * @return */ public static Node reverseList(Node head){ Node pre = null; Node cur = head; while(cur != null){ cur = head.next; head.next = pre; pre = head; head = cur; } return pre; } /** * 获得链表的中间节点,若是单节点链表则返回头结点 * 思路:申请两个变量(指针)pre、cur,pre指向头结点,cur指向头结点的下一个结点,然后pre每次走一步,cur每次走两步,当cur为null或者cur的下一结点为null则此时pre即为中间节点 * @param head * @return */ public static Node getMiddleNode(Node head) { if(head == null) { return head; } Node pre = head; Node cur = head.next; while(cur != null && cur.next != null){ pre = pre.next; cur = cur.next.next; } return pre; } /** * 判断一个链表是否有环 * 思路:申请两个变量(指针)pre、cur指向头结点,pre每次走一步,cur每次走两步,若pre等于cur则说明有环 * @param head * @return */ public static boolean isCircle(Node head) { Node pre = head; Node cur = head; while(cur != null && cur.next != null){ pre=pre.next; cur=cur.next.next; if(pre == cur){ return true; } } return false; } /** * 合并两个有序链表为一个升序链表 * * @param head1 有序链表1的头节点 * @param head2 有序链表2的头节点 * @return */ public static Node merageOrderedList(Node head1, Node head2) { if (head1 == null) { return head2; } if (head2 == null) { return head1; } Node temp1 = head1; Node temp2 = head2; Node tempHead1 = head1; Node tempHead2 = head2; /*判断链表1是否升序,若不是则反转链表1*/ while(temp1 != null && temp1.next != null){ if(temp1.data > temp1.next.data){ tempHead1 = reverseList(tempHead1); break; } temp1 = temp1.next; } /*判断链表2是否升序,若不是则反转链表2*/ while(temp2 != null && temp2.next != null){ if(temp2.data > temp2.next.data){ tempHead2 = reverseList(tempHead2); break; } temp2 = temp2.next; } //用变量head保存合并后有序链表的头节点 Node head = null; if(tempHead1.data < tempHead2.data){ head = tempHead1; tempHead1 = tempHead1.next; }else { head = tempHead2; tempHead2 = tempHead2.next; } Node cur = head; /*执行合并两个链表*/ while(tempHead1 != null && tempHead2 != null){ if(tempHead1.data < tempHead2.data){ cur.next= tempHead1; tempHead1= tempHead1.next; cur = cur.next; }else{ cur.next = tempHead2; tempHead2 = tempHead2.next; cur = cur.next; } } /*执行合并操作结束后,若其中一个链表不为空则将该链表接到合并链表之后*/ if(tempHead1!= null){ cur.next = tempHead1; } if(tempHead2!= null){ cur.next = tempHead2; } return head; } /** * 判断一个单向链表是否为回文链表 * 思路:反转后半部分链表,然后与前半部分比对,若有不同则不是回文链表,否则是回文链表,然后反转链表复原并拼接到前半部分 * @param head * @return */ public static boolean isPalindrome(Node head){ if(head == null || head.next == null){ return false; } boolean flag = true; //找到链表的中间节点 Node pre = getMiddleNode(head); //反转后半部分的链表 Node reverseHead = reverseList(pre.next); //用cur临时存储一份反转链表的头结点 Node cur = reverseHead; Node helpHead = head; while (cur != null){ if(!cur.data.equals(helpHead.data)){ flag = false; break; } cur = cur.next; helpHead = helpHead.next; } pre.next = reverseList(reverseHead); return flag; } public static void main(String[] args){ Node head = new Node(1); head.next = new Node(2); head.next.next = new Node(3); head.next.next.next = new Node(4); boolean isCircle = isCircle(head); boolean palindrome = isPalindrome(head); Node middle = getMiddleNode(head); System.out.println("是否为环:" + isCircle); System.out.println("是否是回文串"+palindrome); System.out.println("中间节点:" + middle.data); // System.out.println(); // Node reverse = reverseList(head); // while (reverse != null){ // System.out.print(reverse.data + " "); // reverse = reverse.next; // } // System.out.println(); // Node root = new Node(3); // root.next = new Node(5); // Node mearge = merageOrderedList(head,reverse); // while(mearge != null) { // System.out.print(mearge.data + " "); // mearge = mearge.next; // } // Node ress = reverseList(head); Node test = new Node(1); test.next = test; System.out.println(isCircle(test)); } }
以上是关于4.单向链表的常见题型的主要内容,如果未能解决你的问题,请参考以下文章