Java实现单链表的各种操作
Java实现单链表的各种操作
主要内容:1.单链表的基本操作
2.删除重复数据
3.找到倒数第k个元素
4.实现链表的反转
5.从尾到头输出链表
6.找到中间节点
7.检测链表是否有环
8.在不知道头指针的情况下删除指定节点
9.如何判断两个链表是否相交并找出相交节点
直接上代码,就是这么奔放~~~
- package pers.ty.$1101datastructure;
- import java.util.Hashtable;
- /**
- * @author Administrator
- * 实现单链表的基本操作,增加删除节点、排序、打印、计算长度
- */
- public class MyLinkedList {
- Node head = null;//链表头的作用
- /**向链表中插入数据
- * @param d:插入数据的内容
- */
- public void addNode(int d){
- Node newNode=new Node(d);
- if(head==null){
- head=newNode;
- return;
- }
- Node tmp=head;
- while(tmp.next!=null){
- tmp=tmp.next;
- }
- //add Node to end
- tmp.next=newNode;
- }
- /**
- * @param index:删除第index个节点
- * @return 成功返回true,失败返回false
- */
- public Boolean deleteNode(int index){
- if(index<1||index>length()){
- return false;//删除元素位置不合理
- }
- //删除链表中的第一个元素
- if(index==1){
- head=head.next;
- return true;
- }
- int i=1;
- Node preNode=head;
- Node curNode=preNode.next;
- while(curNode!=null){
- if(i==index){
- preNode.next=curNode.next;
- return true;
- }
- preNode=curNode;
- curNode=curNode.next;
- i++;
- }
- return true;
- }
- /**
- * @return 返回链表的长度length
- */
- public int length(){
- int length=0;
- Node tmp=head;
- while(tmp!=null){
- length++;
- tmp=tmp.next;
- }
- return length;
- }
- /**
- * 对链表进行排序
- * @return 返回排序后的头结点
- */
- public Node orderList(){
- Node nextNode=null;
- int temp=0;
- Node curNode=head;
- while(curNode.next!=null){
- nextNode=curNode.next;
- while(nextNode!=null){
- if(curNode.data>nextNode.data){
- temp=curNode.data;
- curNode.data=nextNode.data;
- nextNode.data=temp;
- }
- nextNode=nextNode.next;
- }
- curNode=curNode.next;
- }
- return head;
- }
- /**
- * 打印链表中所有数据
- */
- public void printList(){
- Node tmp=head;
- while(tmp!=null){
- System.out.print(tmp.data+" ");
- tmp=tmp.next;
- }
- System.out.println();
- }
- /**
- * 从链表中删除数据的第一种方法
- * 遍历链表,把遍历到的数据存到一个Hashtable中,在遍历过程中若当前访问的值在Hashtable
- * 中存在,则可以删除
- * 优点:时间复杂度低 缺点:需要额外的存储空间来保存已访问过得数据
- */
- public void deleteDuplecate1(){
- Hashtable<Integer,Integer> table=new Hashtable<Integer,Integer>();
- Node tmp=head;
- Node pre=null;
- while (tmp!=null) {
- if(table.containsKey(tmp.data))
- pre.next=tmp.next;
- else{
- table.put(tmp.data, 1);
- pre=tmp;
- }
- tmp=tmp.next;
- }
- }
- /**
- * 从链表中删除重复数据的第二种方法
- * 双重循环遍历
- * 优缺点很明显
- */
- public void deleteDuplecate2(){
- Node p=head;
- while (p!=null) {
- Node q=p;
- while(q.next!=null){
- if(p.data==q.next.data){
- q.next=q.next.next;
- }else{
- q=q.next;
- }
- }
- p=p.next;
- }
- }
- /**
- * @param k:找到链表中倒数第k个节点
- * @return 该节点
- * 设置两个指针p1、p2,让p2比p1快k个节点,同时向后遍历,当p2为空,则p1为倒数第k个节点
- */
- public Node findElem(Node head,int k){
- if(k<1||k>this.length())
- return null;
- Node p1=head;
- Node p2=head;
- for (int i = 0; i < k-1; i++)
- p2=p2.next;
- while (p2.next!=null) {
- p2=p2.next;
- p1=p1.next;
- }
- return p1;
- }
- /**
- * 实现链表的反转
- * @param head链表的头节点
- */
- public void reverseIteratively(Node head){
- Node pReversedHead=head;
- Node pNode=head;
- Node pPrev=null;
- while (pNode!=null) {
- Node pNext=pNode.next;
- if(pNext==null)
- pReversedHead=pNode;
- pNode.next=pPrev;
- pPrev=pNode;
- pNode=pNext;
- }
- this.head=pReversedHead;
- }
- /**
- * 通过递归从尾到头输出单链表
- * @param head
- */
- public void printListReversely(Node head){
- if(head!=null){
- printListReversely(head.next);
- System.out.print(head.data+" ");
- }
- }
- /**
- * 查询单链表的中间节点
- * 定义两个指针,一个每次走一步,一个每次走两步...
- * @param head
- * @return q为中间节点
- */
- public Node searchMid(Node head){
- Node q=head;
- Node p=head;
- while (p!=null&&p.next!=null&&p.next.next!=null) {
- q=q.next;
- p=p.next.next;
- }
- return q;
- }
- /**
- * 在不知道头指针的情况下删除指定节点
- * 链表尾节点无法删除,因为删除后无法使其前驱节点的next指针置为空
- * 其他节点,可以通过交换这个节点与其后继节点的值,然后删除后继节点
- * @param n
- * @return
- */
- public boolean deleteNode(Node n){
- if(n==null||n.next==null)
- return false;
- int tmp=n.data;
- n.data=n.next.data;
- n.next.data=tmp;
- n.next=n.next.next;
- return true;
- }
- /**
- * 判断两个链表是否相交
- * 如果两个链表相交,则肯定有相同的尾节点,遍历两个链表,记录尾节点,看是否相同
- * @param h1链表1的头节点
- * @param h2链表2的头结点
- * @return 是否相交
- */
- public boolean isIntersect(Node h1,Node h2){
- if(h1==null||h2==null)
- return false;
- Node tail1=h1;
- while (tail1.next!=null){
- tail1=tail1.next;
- }
- Node tail2=h2;
- while(tail2.next!=null){
- tail2=tail2.next;
- }
- return tail1==tail2;
- }
- /**
- * 找出相交的第一个节点
- * @param h1
- * @param h2
- * @return
- */
- public Node getFirstMeetNode(Node h1,Node h2){
- if(h1==null||h2==null)
- return null;
- Node tail1=h1;
- int len1=1;
- while (tail1.next!=null){
- tail1=tail1.next;
- len1++;
- }
- Node tail2=h2;
- int len2=1;
- while(tail2.next!=null){
- tail2=tail2.next;
- len2++;
- }
- if(tail1!=tail2){
- return null;
- }
- Node t1=h1;
- Node t2=h2;
- //找出较长的链表先遍历
- if(len1>len2){
- int d=len1-len2;
- while(d!=0){
- t1=t1.next;
- d--;
- }
- }
- if(len1<len2){
- int d=len2-len1;
- while(d!=0){
- t2=t2.next;
- d--;
- }
- }
- while(t1!=t2){
- t1=t1.next;
- t2=t2.next;
- }
- return t1;
- }
- public static void main(String[] args) {
- MyLinkedList list=new MyLinkedList();
- }
- }
Java实现单链表的各种操作的更多相关文章
- Java实现单链表反转操作
单链表是一种常见的数据结构,由一个个节点通过指针方式连接而成,每个节点由两部分组成:一是数据域,用于存储节点数据.二是指针域,用于存储下一个节点的地址.在Java中定义如下: public class ...
- JAVA数据结构——单链表
链表:一. 顺序存储结构虽然是一种很有用的存储结构,但是他有如下几点局限性:1. 因为创造线性表的时候已经固定了空间,所以当需要扩充空间时,就需要重新创建一个地址连续的更大的存储空间.并把原有的数据元 ...
- java实现单链表的增删功能
JAVA 实现单链表的增删功能 package linked; class LinkedTable{ } public class LinkedTableTest { public static vo ...
- 使用java实现单链表(转载自:https://www.cnblogs.com/zhongyimeng/p/9945332.html)
使用java实现单链表----(java中的引用就是指针)转载自:https://www.cnblogs.com/zhongyimeng/p/9945332.html ? 1 2 3 4 5 6 7 ...
- java实现单链表常见操作
一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashM ...
- 数据结构——Java实现单链表
一.分析 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表中的数据是以结点来表示的,每个结点由元素和指针构成.在Java中,我们可以将单链表定义成一个类,单链表的基 ...
- (java实现)单链表
什么是单链表 在了解单链表之前,你知道什么是链表吗?如果你不知道什么是链表,可以看看我的这篇博客<链表-LinkList> 单链表是链表的其中一种基本结构.一个最简单的结点结构如图所示,它 ...
- java实现单链表、栈、队列三种数据结构
一.单链表 1.在我们数据结构中,单链表非常重要.它里面的数据元素是以结点为单位,每个结点是由数据元素的数据和下一个结点的地址组成,在java集合框架里面 LinkedList.HashMap(数组加 ...
- Java解释单链表中的头插法以及尾插法
单链表属于数据结构中的一种基本结构,是一种线性结构,在此使用Java对其中的头插法以及尾插法进行解释. 首先定义好链表中的节点类: 其中,data代表节点所存放的数据,next代表指向下一节点 对于单 ...
随机推荐
- 【Web动画】CSS3 3D 行星运转 && 浏览器渲染原理
承接上一篇:[CSS3进阶]酷炫的3D旋转透视 . 最近入坑 Web 动画,所以把自己的学习过程记录一下分享给大家. CSS3 3D 行星运转 demo 页面请戳:Demo.(建议使用Chrome打开 ...
- ASP.NET MVC Model元数据(一)
ASP.NET MVC Model元数据(一) 前言 在我初学的时候对Model元数据的概念很模糊,或者说是在大脑中没有它的一个模型,作为小白的我去看网上的一些文章还是两眼一黑啥都看不明白,然后我想退 ...
- 使用R画地图数据
用R画地图数据 首先,从这里下载中国地图的GIS数据,这是一个压缩包,完全解压后包含三个文件(bou2_4p.dbf.bou2_4p.shp和bou2_4p.shx),将这三个文件解压到同一个目录下. ...
- C# BS消息推送 SignalR介绍(一)
1. 前言 本文是根据网上前人的总结得出的. 环境: SignalR2.x,VS2015,Win10 介绍 1)SignalR能用来持久客户端与服务端的连接,让我们便于开发一些实时的应用,例如聊天室在 ...
- php使用CI发送qq和163邮件
1.需求 发送邮件 2.介绍 使用CI框架的email类库发送邮件,这里演示QQ和163 3.163使用教程 a.先去163邮件开启smtp邮件. b.在CI的控制器里写下面的代码 $this-> ...
- Android笔记——BaseAdapter的使用
Android中的适配器(Adapter)是数据与视图(View)之间的桥梁,用于对要显示的数据进行处理,并通过绑定到组件进行数据的显示. BaseAdapter是Android应用程序中经常用到的基 ...
- 浅谈 linux 例行性工作 crontab (linux定时任务)
定时任务大家都挺说过,就好比你手机上的闹钟,到了指定的时候就会响起. 今天在对redis缓存进行定时储存时又操作了一把,发现一些细节,写的不好.大家就将就看吧, 首先 简单介绍一下linux 例行性工 ...
- 10最好用的Node.js工具、插件和资料库
每一个称职的程序员都应该拥有一套极好的工具来提高自己的工作效率.在Livecoding.tv 上,那里的程序员分享了10个他们认为是最好用的工具.插件和资料库.据说,以下的这10个工具是使用Node. ...
- python2.7 内置ConfigParser支持Unicode读写
1 python编码基础 对应 C/C++ 的 char 和 wchar_t, Python 也有两种字符串类型,str 与 unicode: str与unicode # -*- coding: ut ...
- JVM学习(4)——全面总结Java的GC算法和回收机制
俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及到的知识点总结如下: 一些JVM的跟踪参数的设置 Java堆的分配参数 -Xmx 和 –Xms 应该保持一个什么关系,可以让系统的 ...