总结提高,与君共勉

概述、

数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结

【链表个数】

【反转链表-循环】

【反转链表-递归】

【查找链表倒数第K个节点】

【查找链表中间节点】

【判断链表是否有环】

【从尾到头打印单链表-递归】

【从尾到头打印单链表-栈】

【由小到大合并有序单链表-循环】

【由小到大合并有序单链表-递归】

通常在java中这样定义单链表结构

<span style="font-family:Microsoft YaHei;font-size:14px;">class Node{
	int value;
	Node next;
	public Node(int n){
		this.value = n;
		this.next = null;
	}
}
</span>

1、链表个数

这个比较简单,不再赘述

<span style="font-family:Microsoft YaHei;font-size:14px;">	// 求单链表的结点个数
	public int getListLen(Node head) {
		int len = 0;
		while (head != null) {
			len++;
			head = head.next;
		}
		return len;
	}</span>

2、反转链表-循环

采用双指针,主要是4行代码,其中2,3俩行完成指针反转,1,4主要是保持head往下指

<span style="font-family:Microsoft YaHei;font-size:14px;">// 反转单链表(循环)
	public Node reverseList(Node head) {
		// 安全性检查
		if (head == null || head.next == null)
			return head;
		Node pre = null;
		Node temp = null;
		while (head != null) {
			// 以下1234均指以下四行代码
			temp = head.next;// 与第4行对应完成头结点移动
			head.next = pre;// 与第3行对应完成反转
			pre = head;// 与第2行对应完成反转
			head = temp;// 与第1行对应完成头结点移动
		}
		return pre;
	}</span>

3、反转链表-递归

<span style="font-family:Microsoft YaHei;font-size:14px;">// 将单链表反转,递归
	public static Node reverseListRec(Node head) {
		if (head == null || head.next == null)
			return head;
		Node reHead = reverseListRec(head.next);
		head.next.next = head;
		head.next = null;
		return reHead;
	}</span>

4、查找链表倒数第K个节点

双指针法,不多解释

<span style="font-family:Microsoft YaHei;font-size:14px;">// 查找单链表倒数第K个结点 双指针法
	public Node reKNode(Node head, int k) {
		if (head == null)
			return head;
		int len = getListLen(head);
		if (k > len)
			return null;
		Node targetK = head;
		Node nextK = head;
		// 先走到K个位置
		for (int i = 0; i < k; i++) {
			nextK = nextK.next;
		}
		// 再和头结点一起走,nextk走到结尾,此时targetk为倒数第K个节点
		while (nextK != null) {
			nextK = nextK.next;
			targetK = targetK.next;
		}
		return targetK;
	}</span>

5、查找链表中间节点

快慢指针,不多解释

<span style="font-family:Microsoft YaHei;font-size:14px;">public Node getMid(Node head) {
		// 类似的快慢指针法
		// 安全性检查
		if (head == null || head.next == null)
			return head;
		Node target = head;
		Node temp = head;
		while (temp != null && temp.next != null) {
			target = target.next;
			temp = temp.next.next;
		}
		return target;
	}</span>

6、判断链表是否有环

主要还是快慢指针,如果快的指针能够追上慢指针则有环

<span style="font-family:Microsoft YaHei;font-size:14px;">// 判断一个单链表中是否有环,快慢指针
	public boolean hasCycle(Node head) {
		boolean flag = false;
		Node p1 = head;
		Node p2 = head;
		while (p1 != null && p2 != null) {
			p1 = p1.next;
			p2 = p2.next.next;
			if (p2 == p1) {
				flag = true;
				break;
			}
		}
		return flag;
	}</span>

7、从尾到头打印单链表-递归

<span style="font-family:Microsoft YaHei;font-size:14px;">// 从尾到头打印单链表(递归)
	public void reList1(Node head) {
		// 安全性检查
		if (head == null)
			return;
		else {
			reList1(head.next);
			System.out.println(head.value);
		}

	}</span>

8、从尾到头打印单链表-栈

利用栈FILO的性质,先存储节点然后输出每个栈的节点值

<span style="font-family:Microsoft YaHei;font-size:14px;">// 从尾到头打印单链表(栈)
	public void reList2(Node head) {
		Stack<Node> s = new Stack<Node>();
		while (head != null) {
			s.push(head);
			head = head.next;
		}
		while (!s.isEmpty()) {
			System.out.println(s.pop().value);
		}
	}</span>

9、由小到大合并有序单链表-循环

<span style="font-family:Microsoft YaHei;font-size:14px;">	// 由小到大合并俩个有序的单链表(循环)
	public Node mergeSort1(Node head1, Node head2) {
		// 安全性检查
		if (head1 == null)
			return head2;
		if (head2 == null)
			return head1;
		// 新建合并节点
		Node target = null;
		// 确定第一个元素的节点
		if (head1.value > head2.value) {
			target = head2;
			head2 = head2.next;
		} else {
			target = head1;
			head1 = head1.next;
		}
		target.next = null;
		// 开始合并
		Node mergeHead = target;
		while (head1 != null && head2 != null) {
			// 当两个链表都不为空
			if (head1.value > head2.value) {
				target.next = head2;
				head2 = head2.next;
			} else {
				target.next = head1;
				head1 = head1.next;
			}
			target = target.next;
			target.next = null;
		}
		if (head1 == null)
			target.next = head2;
		else
			target.next = head1;
		return mergeHead;

	}</span>

10、由小到大合并有序单链表-递归

<span style="font-family:Microsoft YaHei;font-size:14px;">// 由小到大合并俩个有序的单链表(递归)
	public Node mergeSort2(Node head1, Node head2) {
		if (head1 == null)
			return head2;
		if (head2 == null)
			return head1;
		if (head1.value > head2.value) {
			head2.next = mergeSort2(head2.next, head1);
			return head2;
		} else {
			head1.next = mergeSort2(head1.next, head2);
			return head1;
		}
	}</span>

java单链表常用操作的更多相关文章

  1. java实现单链表常见操作

    一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...

  2. Java单链表反转 详细过程

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/guyuealian/article/details/51119499 Java单链表反转 Java实 ...

  3. java 单链表 练习

    练习一下java单链表的简单习题 package com.test1; import java.util.Stack; public class SingleListDemo { /** * 返回单链 ...

  4. Java单链表反转图文详解

    Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...

  5. Java实现单链表反转操作

    单链表是一种常见的数据结构,由一个个节点通过指针方式连接而成,每个节点由两部分组成:一是数据域,用于存储节点数据.二是指针域,用于存储下一个节点的地址.在Java中定义如下: public class ...

  6. JAVA单链表的实现-不带头结点但带有尾指针

    1,本程序实现了线性表的链式存储结构.实现的链表带有两个指针,一个始终指向链表中的第一个结点,另一个指针始终指向链表中的最后一个结点. 之所以设置尾指针,是因为,在插入元素到链表中的末尾时,可以通过尾 ...

  7. java 单链表反转

    最近与人瞎聊,聊到各大厂的面试题,其中有一个就是用java实现单链表反转.闲来无事,决定就这个问题进行一番尝试. 1.准备链表 准备一个由DataNode组成的单向链表,DataNode如下: pub ...

  8. Java单链表、双端链表、有序链表实现

    单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见htt ...

  9. java单链表代码实现

    用惯了C++,java写起来果然不太爽...不废话了,上代码... package javaInnerclassDemo; class Link{ class Node{ private String ...

随机推荐

  1. python脚本批量生成数据

    在平时的工作中,经常会遇到造数据,特别是性能测试的时候更是需要大量的数据.如果一条条的插入数据库或者一条条的创建数据,效率未免有点低.如何快速的造大量的测试数据呢?在不熟悉存储过程的情况下,今天给大家 ...

  2. Python3 SMTP发送邮件

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. python的smtplib提供了一 ...

  3. Gradle 1.12用户指南翻译——第四十九章. Build Dashboard 插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  4. Why Doesn't Python Have Switch/Case?

    Why Doesn't Python Have Switch/Case? Tuesday, June 09, 2015 (permalink) Unlike every other programmi ...

  5. SuperVideo,一款直播,点播,投屏并有的app

    应用名称:SuperVideo应用简介: 1.聚合海量视频,视频源来源于搜狐,乐视,优酷, 腾讯等主流视频网站的丰富视频内容,最新院线大片,热播剧随时看 2.基于百度云解码,享受云解码支持RMVB,M ...

  6. JVM远程DEBUG(JPDA )

    原理 1. JPDA简介 JPDA(Java Platform Debugger Architecture)为Java平台上的调试器定义了一个标准的体系结构.该体系结构包括3个主要组成部分:JVM T ...

  7. 亲密接触Redis-第二天(Redis Sentinel)

    简介 经过上次轻松搭建了一个Redis的环境并用Java代码调通后,这次我们要来看看Redis的一些坑以及Redis2.8以后带来的一个新的特性即支持高可用特性功能的Sentinel(哨兵). Red ...

  8. JAVA面向对象-----值交换(基本数据类型 数组类型 对象的值 字符串的)

    JAVA面向对象-–值交换 基本数据类型交换 数组类型交换 对象的值交换 字符串的值交换 恩,没错,又是贴图,请大家见谅,我也是为了多写几个文章,请大家谅解. 字符串的值交换: 交换值失败. 这个文章 ...

  9. 程序员的自我修养-----Java开发的必须知道的几个注意点

    1. 将一些需要变动的配置写在属性文件中 比如,没有把一些需要并发执行时使用的线程数设置成可在属性文件中配置.那么你的程序无论在DEV环境中,还是TEST环境中,都可以顺畅无阻地运行,但是一旦部署在P ...

  10. JDOM生成、解析XML实例

    import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import j ...