继前面实现ArrayList后,今天和小伙伴一起实现LinkedList,LinkedList实现我们采用双向链表来实现,在每次查找时候,如果该查找元素位于该链表的前半段,则从开始检索,如果位于链表的后半段,则从尾部开始检索。以下先贴出代码:

  1. package com.david.duan;
  2.  
  3. import java.util.Iterator;
  4.  
  5. public class MyLinkedList implements Iterable<Student>{
  6. //表示该链表的长度
  7. private int theSize;
  8. //每次链表被修改就增加此值
  9. private int modCount;
  10. //链表的头元素
  11. private Node<Student> beginMarker;
  12. //链表的尾元素
  13. private Node<Student> endMarker;
  14. //使用内部类来实现链表的每一个节点,每个节点有一个指向下一个元素的next,指向上一个元素的prev,以及自身的data
  15. private static class Node<Student> {
  16. public Node(Student data, Node<Student> prev, Node<Student> next) {
  17. this.data = data;
  18. this.prev = prev;
  19. this.next = next;
  20. }
  21. public Student data;
  22. public Node<Student> prev;
  23. public Node<Student> next;
  24. }
  25. //链表的构造方法
  26. public MyLinkedList () {
  27. clear();
  28. }
  29. //清除链表,即使得链表的头元素指向链表的尾元素
  30. public void clear () {
  31. beginMarker = new Node<Student>(null, null, null);
  32. endMarker = new Node<Student>(null, beginMarker, null);
  33. beginMarker.next = endMarker;
  34. }
  35. //返回链表的长度
  36. public int size() {
  37. return theSize;
  38. }
  39. //判断链表是否为空
  40. public boolean isEmplty() {
  41. return size() == 0;
  42. }
  43. //向链表中添加元素
  44. public boolean add(Student x) {
  45. add(size(), x);
  46. return true;
  47. }
  48.  
  49. public void add(int idx, Student x) {
  50. addBefore(getNode(idx), x);
  51. }
  52. //获取该节点的data
  53. public Student get(int idx) {
  54. return getNode(idx).data;
  55. }
  56. //设置该节点的值
  57. public Student set(int idx, Student newData) {
  58. Node<Student> oldNode = getNode(idx);
  59. Student oldData = oldNode.data;
  60. oldNode.data = newData;
  61. return oldData;
  62. }
  63. //删除该节点,并返回该节点的值
  64. public Student remove(int idx) {
  65. return remove(getNode(idx));
  66. }
  67.  
  68. private Student remove(Node<Student> p) {
  69. p.prev.next = p.next;
  70. p.next.prev = p.prev;
  71. theSize--;
  72. modCount++;
  73. return p.data;
  74. }
  75. //执行添加
  76. private void addBefore (Node<Student> p, Student x) {
  77. Node<Student> newNode = new Node<Student>(x, p.prev, p);
  78. newNode.prev.next = newNode;
  79. p.prev = newNode;
  80. modCount++;
  81. }
  82. //查找节点
  83. private Node<Student> getNode(int idx) {
  84. Node<Student> p;
  85.  
  86. if(idx <0 || idx > size()) {
  87. throw new IndexOutOfBoundsException();
  88. }
  89.  
  90. if(idx < size()/2) {
  91. p = beginMarker.next;
  92. for (int i = 0;i < idx;i++) {
  93. p = p.next;
  94. }
  95. }else {
  96. p = endMarker;
  97. for (int i = size();i>idx;i--) {
  98. p = p.prev;
  99. }
  100. }
  101. return p;
  102. }
  103. //此处类似于前面的ArrayList,用以保存并返回当前元素
  104. @Override
  105. public Iterator<Student> iterator() {
  106. return new LinkedListIterator();
  107. }
  108.  
  109. private class LinkedListIterator implements java.util.Iterator<Student> {
  110.  
  111. private Node<Student> current = beginMarker.next;
  112. private int expectedModCount = modCount;
  113. private boolean okToRemove = false;
  114. @Override
  115. public boolean hasNext() {
  116. return current != endMarker;
  117. }
  118.  
  119. @Override
  120. public Student next() {
  121. if (modCount != expectedModCount ) {
  122. throw new java.util.ConcurrentModificationException();
  123. }
  124. if(!hasNext()) {
  125. throw new java.util.NoSuchElementException();
  126. }
  127. Student nextData = current.data;
  128. current = current.next;
  129. okToRemove = true;
  130. return nextData;
  131. }
  132.  
  133. @Override
  134. public void remove() {
  135. if (modCount != expectedModCount ) {
  136. throw new java.util.ConcurrentModificationException();
  137. }
  138. if(!hasNext()) {
  139. throw new java.util.NoSuchElementException();
  140. }
  141. MyLinkedList.this.remove(current.prev);
  142. okToRemove = false;
  143. expectedModCount++;
  144. }
  145.  
  146. }
  147. }

此处讲解不太详细的地方,欢迎大家留言探讨。

[置顶] 小伙伴们来自己实现LinkedList的更多相关文章

  1. [知了堂学习笔记]_css3特效第二篇--行走的线条&&置顶导航栏

    一.行走的线条. 效果图(加载可能会慢一点儿,请稍等...): html代码: <div class="movingLines"> <img src=" ...

  2. MySQL 上移/下移/置顶

    在编写网站系统时,难免会用到上移.下移.置顶的功能,今天小编就介绍一下我的思路. 首先,需要一张数据表: CREATE TABLE `a` ( `id` ) NOT NULL AUTO_INCREME ...

  3. css3特效第二篇--行走的线条&&置顶导航栏

    一.行走的线条. 效果图(加载可能会慢一点儿,请稍等...): html代码: <div class="movingLines"> <img src=" ...

  4. 在UWP中页面滑动导航栏置顶

    最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms ...

  5. WinFrom窗体始终置顶

    调用WindowsAPI使窗体始终保持置顶效果,不被其他窗体遮盖: [DllImport("user32.dll", CharSet = CharSet.Auto)] privat ...

  6. winform窗体置顶

    winform窗体置顶 金刚 winform 置顶 今天做了一个winform小工具.需要设置置顶功能. 网上找了下,发现百度真的很垃圾... 还是必应靠谱些. 找到一个可以链接. https://s ...

  7. 自定义置顶TOP按钮

    简述一下,分为三个步骤: 1. 添加Html代码 2. 调整Css样式 3. 添加Jquery代码 具体代码如下: <style type="text/css"> #G ...

  8. ahk之路:利用ahk在window7下实现窗口置顶

    操作系统:win7 64位 ahk版本:autohotkey_L1.1.24.03 今天安装了AutoHotkey_1.1.24.03.SciTE.PuloversMacroCreator,重新开始我 ...

  9. Qt中让Qwidget置顶的方法

    一般来是说窗体置顶和取消只要        setWindowFlags(Qt::WindowStaysOnTopHint);        setWindowFlags(Qt::Widget); 要 ...

随机推荐

  1. 保护DNS服务器3大方法

    保护DNS服务器3大方法       DNS全称DomainNameSystem域名解析系统,通俗地说,DNS就是帮助用户在Internet上寻找名称与IP对应的解析服务.为了更方便使用网络资源,DN ...

  2. Android 传感器开发

    如今的智能手机都配备了各种各样的传感器,本文将介绍Android SDK提供的传感器开发接口,并通过简单实例展示怎样使用这些接口. Andriod SDK传感器相关类 android SDK提供的与传 ...

  3. 再造 “手机QQ” 侧滑菜单(三)——视图联动

    代码示例:https://github.com/johnlui/SwiftSideslipLikeQQ 本 文中,我们将一起使用 UINavigationController 来管理主视图,并实现点击 ...

  4. arm:启动代码判断是从nand启动还是从norflash启动,拷贝程序到内存的过程

    一.nand启动和nor启动:[1] CPU从0x00000000位置开始运行程序. 1.nand启动: 如果将S3C2440配置成从NANDFLASH启动(将开发板的启动开关拔到nand端,此时OM ...

  5. null的小扩展

    注意:JavaScript有6种数据类型,其中是五种基本数据类型,分别是:Undefined.Null.Boolean.Number 和String,还有一种复杂的数据类型Object 使用typeo ...

  6. [C#] 网页Html转PDF档(一行程式码解决)

    原文 [C#] 网页Html转PDF档(一行程式码解决) 网页转PDF档做法很多( Convert HTML to PDF in .NET ) 这边纪录一下老外最多人加分的那篇做法,使用wkhtmto ...

  7. 小胖说事24-----property&#39;s synthesized getter follows Cocoa naming convention for returning &#39;owned&#39; objec

    今天在给类的属性命名的时候,用了newValue.就给报错:property's synthesized getter follows Cocoa naming convention for retu ...

  8. Activity生命周期方法的调用顺序project与測试日志

    以下为測试activity的方法的运行顺序   project与測试资源地址 androidproject AndroidManifest.xml <? xml version="1. ...

  9. 图片转换成Base64编码集成到html文件

    首先为什么要这么做?  原因很简单这样可以减少与服务器的请求,当然对于一些浏览器并不支持,如IE8.通常用在手机版网站中,具体转化方法如下: 1.在线打开Base64的编码器将图片编码成Base64 ...

  10. perl encode_json 会产生 UTF-8 (binary) string decode_json 需要一个 UTF-8 (binary) string

    encode_json $json_text = encode_json $perl_scalar Converts the given Perl data structure to a UTF-8 ...