java单链表常用操作
总结提高,与君共勉
概述、
数据结构与算法亘古不变的主题,链表也是面试常考的问题,特别是手写代码常常出现,将从以下方面做个小结
【链表个数】
【反转链表-循环】
【反转链表-递归】
【查找链表倒数第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单链表常用操作的更多相关文章
- java实现单链表常见操作
一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...
- Java单链表反转 详细过程
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/guyuealian/article/details/51119499 Java单链表反转 Java实 ...
- java 单链表 练习
练习一下java单链表的简单习题 package com.test1; import java.util.Stack; public class SingleListDemo { /** * 返回单链 ...
- Java单链表反转图文详解
Java单链表反转图文详解 最近在回顾链表反转问题中,突然有一些新的发现和收获,特此整理一下,与大家分享 背景回顾 单链表的存储结构如图: 数据域存放数据元素,指针域存放后继结点地址 我们以一条 N1 ...
- Java实现单链表反转操作
单链表是一种常见的数据结构,由一个个节点通过指针方式连接而成,每个节点由两部分组成:一是数据域,用于存储节点数据.二是指针域,用于存储下一个节点的地址.在Java中定义如下: public class ...
- JAVA单链表的实现-不带头结点但带有尾指针
1,本程序实现了线性表的链式存储结构.实现的链表带有两个指针,一个始终指向链表中的第一个结点,另一个指针始终指向链表中的最后一个结点. 之所以设置尾指针,是因为,在插入元素到链表中的末尾时,可以通过尾 ...
- java 单链表反转
最近与人瞎聊,聊到各大厂的面试题,其中有一个就是用java实现单链表反转.闲来无事,决定就这个问题进行一番尝试. 1.准备链表 准备一个由DataNode组成的单向链表,DataNode如下: pub ...
- Java单链表、双端链表、有序链表实现
单链表: insertFirst:在表头插入一个新的链接点,时间复杂度为O(1) deleteFirst:删除表头的链接点,时间复杂度为O(1) 有了这两个方法,就可以用单链表来实现一个栈了,见htt ...
- java单链表代码实现
用惯了C++,java写起来果然不太爽...不废话了,上代码... package javaInnerclassDemo; class Link{ class Node{ private String ...
随机推荐
- The specified JRE installation does not exist异常的原因和解决办法
今天,回首为了学习新框架,于是将JDK的版本从1.7开发标配版换成了1.8,一切前期很顺利,完成了新框架的测试和体验,但在运行原有项目的时候问题出现了,爆出了The specified JRE ins ...
- 【转】使用virtualenv在ubuntu上搭建python 3开发环境
ubuntu 13.04默认的python版本是2.7的,想在其上做python3的开发会遇到问题.比如要使用pip安装软件包时,默认安装的就是python2的包.如果想安装python3的包,就需要 ...
- [extjs5学习笔记]第三十八节 sencha CMD 6.0.0.220版本安装
本文地址:http://blog.csdn.net/sushengmiyan/article/details/46740381 简介 sencha cmd 6安装过程不需要UAC控制了对于widnow ...
- 2.Cocos2dx 3.2中的重力系统Box2D
1 添加Box2D相关的库 步骤1:右击项目所在的解决方案à添加->现有项目àE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\external\Box2D ...
- SQLite 数据类型(http://www.w3cschool.cc/sqlite/sqlite-data-types.html)
SQLite 数据类型 SQLite 数据类型是一个用来指定任何对象的数据类型的属性.SQLite 中的每一列,每个变量和表达式都有相关的数据类型. 您可以在创建表的同时使用这些数据类型.SQLite ...
- 并发计算模型BSP与SEDA
1 BSP批量同步并行计算 BSP(Bulk Synchronous Parallel)批量同步并行计算用来解决并发编程难的问题.名字听起来有点矛盾,又是同步又是并行的.因为计算被分组成一个个超 ...
- 无网络环境下安装Dynamics CRM
在安装CRM时会需要很多的组件支持,没有这些组件是没法安装的,一般我们都是选择机器联网后在线安装,但也有特殊情况确实不能联网的,可参考这篇文章 https://blogs.msdn.microsoft ...
- iOS9中关于地址簿ABAddressBookXXX之类方法被废弃的解决
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 在iOS9的SDK中我们会发现原来地址簿权限查询,获取以及创建 ...
- 3.Lucene3.x API分析,Director 索引操作目录,Document,分词器
1 Lucene卡发包结构分析 包名 功能 org.apache.lucene.analysis Analysis提供自带的各种Analyzer org.apache.lucene.colla ...
- 自己动手实现一个Android Studio插件
在使用Android Studio开发的时候,大部分人都会使用一些插件来提高开发效率,例如我们所熟知的butternife,selector,,GsonFormat等,这些分别从不同的原理来帮助我们提 ...