自定义链表并实现链表反转(面试:分别使用递归和循环并进行比较)

自定义节点类Node.java,用于创建链表

package com.zr.demo;
/**
 * @version: 1.0.0
 * @Description: 节点类,用于创建链表
 * @author: ZR
 * @date: 2019年12月25日 下午8:12:11
 */
public class Node<T> {

	private final T value;
	private Node<T> next;
	
	public Node(T value) {
		this.value=value;
		this.next=null;
	}

	public Node<T> getNext() {
		return next;
	}

	public void setNext(Node<T> next) {
		this.next = next;
	}

	public T getValue() {
		return value;
	}
	
	/**
	 * 输出链表
	 * @param <T>
	 * @param head
	 */
	public static <T> void printLinkedList(Node<T> head) {
		while (head!=null) {
			System.out.print(head.getValue()+" ");
			head=head.getNext();
		}
		System.out.println();
	}
}

自定义链表类LinkedList.java

package com.zr.demo;

import java.util.Arrays;
import java.util.List;

/**
 * @version: 1.0.0
 * @Description: 自定义链表
 * @author: ZR
 * @date: 2019年12月25日 下午8:12:33
 */
public class LinkedList {
	
	/**
	 * 使用递归创建链表
	 * @param <T>
	 * @param data
	 * @return
	 */
	public <T> Node<T> createLinkedListByRecursion(List<T> data) {
		if (data.isEmpty()) {
			return null;
		}
		
		Node<T> firstNode=new Node<T>(data.get(0));
		firstNode.setNext(createLinkedListByRecursion(data.subList(1, data.size())));
		return firstNode;
	}
	
	/**
	 * 使用递归实现链表反转
	 * @param <T>
	 * @param head 头节点
	 * @return 返回新的节点
	 */
	public <T> Node<T> reverseLinkedListByRecursion(Node<T> head) {
		if (head==null||head.getNext()==null) {
			return head;
		}
		Node<T> newHead=reverseLinkedListByRecursion(head.getNext());
		head.getNext().setNext(head);
		head.setNext(null);
		return newHead;
	}
	
	/**
	 * 使用循环创建链表
	 * @param <T>
	 * @param size 链表大小
	 * @return
	 */
	public Node<Integer> createLinkedListByLoop(int size) {
		Node<Integer> prev=null;
		Node<Integer> head=null;
		for (int i = 1; i <= size; i++) {
			Node<Integer> node=new Node<Integer>(i);
			if (prev==null) {
				head=node;
			}else {
				prev.setNext(node);
			}
			prev=node;
		}
		return head;
	}
	
	/**
	 * 使用循环实现链表反转
	 * @param <T>
	 * @param head 头节点
	 * @return 返回新的节点
	 */
	public <T> Node<T> reverseLinkedListByLoop(Node<T> head) {
		Node<T> newHead=null;
		Node<T> curNode=head;
		
		while(curNode!=null) {
			Node<T> next=curNode.getNext();
			curNode.setNext(newHead);
			newHead=curNode;
			curNode=next;
		}
		
		return newHead;
	}

	/**
	 * 通过递归和循环两种方法比较。
	 * 可知:递归在处理大量数据时会造成栈溢出,
	 * 		而使用循环则不仅可以正确处理而且效率高
	 * @param args
	 */
	public static void main(String[] args) {
		LinkedList reverse=new LinkedList();
		
		System.out.println("Test normal linkedlist by loop:");
		Node.printLinkedList(reverse.reverseLinkedListByLoop(reverse.createLinkedListByLoop(5)));//输出结果:5 4 3 2 1
		System.out.println("Test large linkedlist by loop:");
		reverse.reverseLinkedListByLoop(reverse.createLinkedListByLoop(1000000));//因为1000000数据太多,所以不再输出,直接运行,结果很快就执行成功
	
		System.out.println("Test normal linkedlist by recursion:");
		Node.printLinkedList(reverse.reverseLinkedListByRecursion(reverse.createLinkedListByRecursion(Arrays.asList(1,2,3,4,5))));//输出结果:5 4 3 2 1
		System.out.println("Test large linkedlist by recursion:");
		Node.printLinkedList(reverse.reverseLinkedListByRecursion(reverse.createLinkedListByLoop(1000000)));//输出结果异常:Exception in thread "main" java.lang.StackOverflowError
	
	}
}

通过递归和循环两种方法比较。

可知:递归在处理大量数据时会造成栈溢出,而使用循环则不仅可以快速处理,而且不会造成资源占用导致的内存消耗

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值