数据结构专题——反转链表问题(java实现)

数据结构专题——反转链表问题(java实现)
问题:给定一个单链表的头结点,反转该链表后,返回新链表的表头

首先依旧是链表的定义:(leetcode方式)

class ListNode {
    int val;
    ListNode next;

    public ListNode(int val) {
        this.val = val;
        next = null;
    }
}
方法一:使用栈(不推荐,需要额外开辟O(n)的空间)
public static ListNode reverseLinkedListByStack(ListNode head) {
		if (head == null || head.next == null) {
			return head;
		}
		//创建栈将结点并将链表结点从头到尾入栈
		Stack<ListNode> stack = new Stack<>();
		while (head != null) {
			stack.push(head);
			head = head.next;
		}
		//拿出栈中第一个结点作为新链表的表头
		if(!stack.isEmpty())
			head = stack.pop();
		ListNode cur = head;
		//依次拿出结点以尾插的方式接入表头
		while (!stack.empty()) {
			ListNode Node = stack.pop();
			Node.next = null;
			cur.next = Node;
			cur = Node;
		}
		return head;
	}
方法二:使用一个临时结点以头插法的方式进行连接新链表(最简单也最好理解)
public static ListNode reverseLinkedListByNode(ListNode head) {
		if (head == null || head.next == null) {
			return head;
		}
		//创建一个辅助结点
		ListNode Node = new ListNode(0);
		//从原来链表上一个一个拿用头插法的方式接到这个辅助结点上 
		ListNode cur = head;
		while(cur != null) {
			ListNode temp = cur.next;
			cur.next = Node.next;
			Node.next = cur;
			cur = temp;
		}
		//返回辅助结点的next结点就是反转后的表头
		return Node.next;
	}
方法三:使用双指针的方式进行(不需要额外开辟内存,推荐)
public static ListNode reverseLinkedListNoByNode(ListNode head) {
        if (head == null || head.next == null) {
			return head;
		}
        //使用双指针的方式,两个指针往前走,依次进行改变指针指向向前
        ListNode pre = null;
        ListNode cur = head;
        while (cur != null) {
            //这里需要一个临时指针,要不cur往前指的时候就找不到后面了
            ListNode temp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = temp;
        }
        //返回辅助结点的next结点就是反转后的表头
        return cur;
    }
方法四:递归(不好理解,本人理解的不是很好,这里没写注释,就不影响读者思路了)
public static ListNode reverseLinkedListByRecursive(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverseLinkedListByRecursive(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
测试方法(注:该测试方法需要分开测试)
public static void main(String[] args) {
          int[] arr = new int[]{1,2,3,4,5}; 
	        ListNode list = initList(arr);
	        System.out.println(printList(list));
	        ListNode newList = null;
	        //第一种方法反转链表
	        newList = reverseLinkedListByNode(list);
	        System.out.println(printList(newList));
	        //第二种方法反转链表
//	        newList = reverseLinkedListNoByNode(list);
//	        System.out.println(printList(newList));
	        //第三种方法反转链表
//	        newList = reverseLinkedListByStack(list);
//	        System.out.println(printList(newList));
	        //第四种方法反转链表
//	        newList = reverseLinkedListByRecursive(list);
//	        System.out.println(printList(newList));
    }
初始化链表的方法
	/**
	 *  初始化链表
	 * 	@return 链表头结点
	 */   
public static ListNode initList(int[] array) {
        ListNode node = new ListNode(0);
        ListNode head = node;
        for(int i = 0; i < array.length; i++) {
            ListNode temp = new ListNode(array[i]);
            node.next = temp;
            node = node.next;
        }
        return head.next;
    }
打印链表的方法
	/**
	 * 打印链表
	 * @param head
	 * @return 链表所有元素组成的字符串
	 */
public static String printList(ListNode head) {

    if(head == null) {
        return "";
    }

    ListNode cur = head;
    StringBuilder sb = new StringBuilder();
    while(cur != null) {
        sb.append(cur.val).append("->");
        cur = cur.next;
    }
    sb.append("null");
    return sb.toString();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值