一:单向链表基本介绍

链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。下面对单向链表做一个介绍。

单向链表是一种线性表,实际上是由节点(Node)组成的,一个链表拥有不定数量的节点。其数据在内存中存储是不连续的,它存储的数据分散在内存中,每个结点只能也只有它能知道下一个结点的存储位置。由N各节点(Node)组成单向链表,每一个Node记录本Node的数据及下一个Node。向外暴露的只有一个头节点(Head),我们对链表的所有操作,都是直接或者间接地通过其头节点来进行的。

上图中最左边的节点即为头结点(Head),但是添加节点的顺序是从右向左的,添加的新节点会被作为新节点。最先添加的节点对下一节点的引用可以为空。引用是引用下一个节点而非下一个节点的对象。因为有着不断的引用,所以头节点就可以操作所有节点了。
下图描述了单向链表存储情况。存储是分散的,每一个节点只要记录下一节点,就把所有数据串了起来,形成了一个单向链表。

节点(Node)是由一个需要储存的对象及对下一个节点的引用组成的。也就是说,节点拥有两个成员:储存的对象、对下一个节点的引用。下面图是具体的说明:

二、单项链表的实现

package com.zjn.LinkAndQueue;/*** 自定义链表设计* * @author zjn**/
public class MyLink {Node head = null; // 头节点/*** 链表中的节点,data代表节点的值,next是指向下一个节点的引用* * @author zjn**/class Node {Node next = null;// 节点的引用,指向下一个节点int data;// 节点的对象,即内容public Node(int data) {this.data = data;}}/*** 向链表中插入数据* * @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;}tmp.next = newNode;}/*** * @param index:删除第index个节点* @return*/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 false;}/*** * @return 返回节点长度*/public int length() {int length = 0;Node tmp = head;while (tmp != null) {length++;tmp = tmp.next;}return length;}/*** 在不知道头指针的情况下删除指定节点* * @param n* @return*/public boolean deleteNode11(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;System.out.println("删除成功!");return true;}public void printList() {Node tmp = head;while (tmp != null) {System.out.println(tmp.data);tmp = tmp.next;}}public static void main(String[] args) {MyLink list = new MyLink();list.addNode(5);list.addNode(3);list.addNode(1);list.addNode(2);list.addNode(55);list.addNode(36);System.out.println("linkLength:" + list.length());System.out.println("head.data:" + list.head.data);list.printList();list.deleteNode(4);System.out.println("After deleteNode(4):");list.printList();}
}

三、链表相关的常用操作实现方法

1. 链表反转

/*** 链表反转* * @param head* @return*/public Node 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;return this.head;}

2. 查找单链表的中间节点

采用快慢指针的方式查找单链表的中间节点,快指针一次走两步,慢指针一次走一步,当快指针走完时,慢指针刚好到达中间节点。

/*** 查找单链表的中间节点* * @param head* @return*/public Node SearchMid(Node head) {Node p = this.head, q = this.head;while (p != null && p.next != null && p.next.next != null) {p = p.next.next;q = q.next;}System.out.println("Mid:" + q.data);return q;}

3. 查找倒数第k个元素

采用两个指针P1,P2,P1先前移K步,然后P1、P2同时移动,当p1移动到尾部时,P2所指位置的元素即倒数第k个元素 。

/*** 查找倒数 第k个元素* * @param head* @param k* @return*/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; i++)// 前移k步p1 = p1.next;while (p1 != null) {p1 = p1.next;p2 = p2.next;}return p2;}

4. 对链表进行排序

/*** 排序* * @return*/public Node orderList() {Node nextNode = null;int tmp = 0;Node curNode = head;while (curNode.next != null) {nextNode = curNode.next;while (nextNode != null) {if (curNode.data > nextNode.data) {tmp = curNode.data;curNode.data = nextNode.data;nextNode.data = tmp;}nextNode = nextNode.next;}curNode = curNode.next;}return head;}

5. 删除链表中的重复节点

/*** 删除重复节点*/public void deleteDuplecate(Node head) {Node p = head;while (p != null) {Node q = p;while (q.next != null) {if (p.data == q.next.data) {q.next = q.next.next;} elseq = q.next;}p = p.next;}}

6. 从尾到头输出单链表,采用递归方式实现

/*** 从尾到头输出单链表,采用递归方式实现* * @param pListHead*/public void printListReversely(Node pListHead) {if (pListHead != null) {printListReversely(pListHead.next);System.out.println("printListReversely:" + pListHead.data);}}

7. 判断链表是否有环,有环情况下找出环的入口节点

/*** 判断链表是否有环,单向链表有环时,尾节点相同* * @param head* @return*/public boolean IsLoop(Node head) {Node fast = head, slow = head;if (fast == null) {return false;}while (fast != null && fast.next != null) {fast = fast.next.next;slow = slow.next;if (fast == slow) {System.out.println("该链表有环");return true;}}return !(fast == null || fast.next == null);}/*** 找出链表环的入口* * @param head* @return*/public Node FindLoopPort(Node head) {Node fast = head, slow = head;while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;if (slow == fast)break;}if (fast == null || fast.next == null)return null;slow = head;while (slow != fast) {slow = slow.next;fast = fast.next;}return slow;}

【数据结构】链表的原理及java实现相关推荐

  1. java链表实现_链表的原理及java实现

    一:单向链表基本介绍 链表是一种数据结构,和数组同级.比如,Java中我们使用的ArrayList,其实现原理是数组.而LinkedList的实现原理就是链表了.链表在进行循环遍历时效率不高,但是插入 ...

  2. java什么时候用链表_java链表的原理及使用方法

    链表是一种物理存储单元上非连续.非顺序(即每个数据对象data存放的位置可以是非连续.非顺序的)的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表中每一个元素称为结点,结点可以在运 ...

  3. 单链表的面试题——Java数据结构

    单链表的面试题--Java数据结构 说明 本篇博客介绍的是Java数据结构中的单链表,以及一点栈的知识,主要进行代码演示面试中对单链表这一部分的工作要求. 本文介绍顺序如下: (1)什么是单链表,以及 ...

  4. 猴子选大王 java_基于java数据结构链表写的猴子选大王

    [实例简介] 基于java数据结构链表写的猴子选大王,其实就是一个约瑟夫环问题,采用java数据结构链表写的.有点小问题.当输入一只猴子,报数为1时删除会出错.没有实现动态显示猴子的添加和删除. [实 ...

  5. Java数据结构链表面试题 作者:哇塞大嘴好帥(哇塞大嘴好帅) --持续更新

    作者:哇塞大嘴好帥(哇塞大嘴好帅) Java数据结构链表面试题 4.1.查询链表有效数据个数 //判断有效数据个数 public int validDate(){//创建临时变量NodeDate no ...

  6. java数据结构-链表详解

    文章目录 1.数据结构-链表详解 1.1单链表 1.1.1单链表节点的尾部添加 1.1.2单链表节点的自动排序添加 1.1.3单链表节点的修改 1.1.4单链表节点的删除 1.2单链表面试题 1.2. ...

  7. [XJTUSE]数据结构学习——第一章 线性表 1.3 单链表的实现(JAVA)

    文章目录 1.3 单链表的实现(JAVA) 1.curr指针与头结点的说明 2.插入和删除操作的说明 插入 删除 1.3 单链表的实现(JAVA) 链表是由一系列叫做表的结点(node)的对象组成的, ...

  8. 跳跃表(Skip list)原理与java实现

    转载自 [算法导论33]跳跃表(Skip list)原理与java实现 Skip list是一个用于有序元素序列快速搜索的数据结构,由美国计算机科学家William Pugh发明于1989年.它的效率 ...

  9. Redis——5种数据结构底层实现原理

    目录 一.Redis 简介 Redis 的优点 Redis 的安装 测试本地 Redis 性能 二.Redis 五种基本数据结构 1)字符串 string SDS 与 C 字符串的区别 对字符串的基本 ...

最新文章

  1. 原来你是这样的Promise
  2. 一款粉笔最近火了 世界各国数学家为什么集体囤粉笔
  3. 文件被误删不需要绝望,EasyRecovery送你时光机
  4. 数据库实战案例—————记一次TempDB暴增的问题排查
  5. 谁的青春不迷惘,谁的年少不忧伤
  6. xps文件的查看及转换
  7. 新丰机器人_韶关新丰:智能巡检开启配电网运维新模式
  8. idea urule不存在
  9. 计算机检索word文档检索式,完整word版)中国知网等文献检索的一般方法
  10. oracle查询排序id,Oracle查询数据怎么按照甲乙丙丁排序?谢谢
  11. STM32F407 CAN Controller介绍(二)
  12. 惠州全日制计算机学校,惠州市所有中专学校一览表
  13. 一名优秀的数据分析,需要满足哪些基本条件?
  14. 如何安装打印机驱动程序?快速安装的方法
  15. shell下删除文件末尾的空行
  16. wordpress搜索引擎蜘蛛统计插件SEO
  17. 五招保护您的家用路由器安全
  18. Linux时间一直跳回原始时间,Linux时间同步
  19. python(x,y)教程
  20. 梁昌勇 软件工程_改进交互式蚁群算法及其应用

热门文章

  1. 云台山上的那一抹彩霞:少爷心中的白月光
  2. Apache Beam
  3. 《IOS疯狂讲义》雪花飘飘效果实现
  4. IPSEC的原理及配置步骤整理(一)
  5. 智能故障诊断方法总结
  6. 秒懂!原码、反码、补码的转化原来这么简单……
  7. 设置导航栏背景色为透明色的最有效做法
  8. 升米恩斗米仇,驳”开源侵略论”
  9. linux安装whl文件(pip 命令不可用)
  10. 水中铅超标如何处理?除铅吸附材料