zoukankan      html  css  js  c++  java
  • (链表)-反转链表(递归和头插法实现)

      反转一个链表常用的两种实现方式:递归和头插法的方式

    (1)递归实现

    package dsaa.反转链表;
    
    class Node {
    	int val;
    	Node next;
    
    	public Node(Node next, int val) {
    		this.val = val;
    		this.next = next;
    	}
    
    	public Node(int val) {
    		this.val = val;
    	}
    }
    
    public class Solution {
    	/* 采用递归来反转链表 */
    	public static Node reverseList(Node head) {
    		if (head == null || head.next == null) {
    			return head;
    		}
    		Node theNextOfHead = head.next;
    		Node newHead = reverseList(theNextOfHead);
    		theNextOfHead.next = head;
    		head.next = null;
    		return newHead;
    	}
    
    
    	public static void main(String[] args) {
    		Node head = new Node(new Node(new Node(null, 3), 2), 1);
    		Node cur = head;
    		System.out.print("原始的链表:");
    		while (cur != null) {
    			System.out.print(cur.val);
    			cur = cur.next;
    		}
    		Node theNodeOfCurrent = Solution.reverseList(head);
    		System.out.println();
    		System.out.print("反转过后的链表:");
    		while (theNodeOfCurrent != null) {
    			System.out.print(theNodeOfCurrent.val);
    			theNodeOfCurrent = theNodeOfCurrent.next;
    		}
    
    	}
    }
    

      (2)头插法实现

      个人更青睐这一种,采用新建一个空next域的newHead头结点来指向新的反转过后的链表,另外利用了两个指针来保存当前节点和下一节点,cur表示当前节点,next表示下一节点,每次开始时都需要让next称为cur的下一节点,然后开始断开cur和next之间的联系,并每次都让newHead的next域成为当前节点的next域,第一个节点的next域就被赋成了null,后面每次都是上一节点,然后再让当前节点成为newHead的下一节点,即newHead.next = cur,并且移动当前节点的位置到下一位置。

    package dsaa.反转链表;
    
    class Node {
    	int val;
    	Node next;
    
    	public Node(Node next, int val) {
    		this.val = val;
    		this.next = next;
    	}
    
    	public Node(int val) {
    		this.val = val;
    	}
    }
    
    	/* 采用头插法 */
    	public static Node reverseList(Node head) {
    		/**
    		 * 头插法反转链表应该重视的是指针的变换过程
    		 */
    		/* 新建一个新链表的头指针newHead */
    		Node newHead = new Node(-1);
    		/* 用两个指针来表示当前的节点和下一节点 */
    		/* next指针域每次表示为当前节点的下一节点,所以一开始就别再赋值了 */
    		Node current = head;
    		Node next = null;
    		/* 开始判断并遍历原始的链表,构造新的链表 */
    		while (current != null) {
    			/* 先让next指针移到当前节点的下一节点中去 */
    			next = current.next;
    			/* 让现在的链表的第一个节点的下一指针域变成newHead的下一指针域 */
    			/* 但是newHead的一开始的下一指针域是null,所以相当于是让head变成了新链表的头结点 */
    			/* 但是后续的每一次就是让当前链表的头结点指向新链表的第一个节点(非newHead) */
    			current.next = newHead.next;
    			/* 再让newHead指向当前链表的头节点 */
    			newHead.next = current;
    			/* 移动当前节点到下一节点的位置 */
    			current = next;
    		}
    		return newHead.next;
    	}
    
    	public static void main(String[] args) {
    		Node head = new Node(new Node(new Node(null, 3), 2), 1);
    		Node cur = head;
    		System.out.print("原始的链表:");
    		while (cur != null) {
    			System.out.print(cur.val);
    			cur = cur.next;
    		}
    		Node theNodeOfCurrent = Solution.reverseList(head);
    		System.out.println();
    		System.out.print("反转过后的链表:");
    		while (theNodeOfCurrent != null) {
    			System.out.print(theNodeOfCurrent.val);
    			theNodeOfCurrent = theNodeOfCurrent.next;
    		}
    
    	}
    }
    

      

      

  • 相关阅读:
    JVM的即时编译器JIT之简单介绍
    JS脚本动态给标签控件添加事件
    getParameterMap的使用
    IOS开发中判断文件是否存在,不存在则拷贝
    javaweb中解决Cookie中文乱码问题
    网页中的上标和下标实现
    Java中枚举的使用
    ASP.NET 首页性能的4大做法
    httpHandlers和httpModules接口介绍 (5)
    css+div排版如何支持所有浏览器
  • 原文地址:https://www.cnblogs.com/dashenaichicha/p/12572366.html
Copyright © 2011-2022 走看看