-
java实现单项链表(复制,自己总结的在下一篇)
- 一、单向链表的结构。
-
- (1)、首先节点的结构,其中包含本节点内容,以及需要指向下一个节点。
-
-
- Java代码
- private static class Entry<E>{
- E e;
- Entry<E> nextEntry;
-
- public Entry(E e,Entry<E> nextEntry){
- this.e=e;
- this.nextEntry=nextEntry;
- }
- }
-
- private static class Entry<E>{
- E e;
- Entry<E> nextEntry;
-
- public Entry(E e,Entry<E> nextEntry){
- this.e=e;
- this.nextEntry=nextEntry;
- }
- }Java代码
-
-
-
- Java代码
-
-
- 其中e则指向本节点的对象,而nextEntry则指向下一个节点。
-
-
-
- (2)、任何时候都需要知道表头在哪里。毕竟是单向链表嘛,因为只有一个方向,找到了表头就能找到全部。
-
- Java代码
- private Entry<E> head;
-
- private Entry<E> head;
-
- (3)、还可以记录链表中总共有多少个节点。它是在某些判断时为了提高效率而存在的。不是绝对需要的。毕竟知道表头后,一个一个按顺序去寻找就好了。
-
-
- Java代码
- private int size;
-
- public int size(){
- return this.size;
- }
-
- private int size;
-
- public int size(){
- return this.size;
- }
- Java代码
-
-
- 好了有这三样,就足够了。就看我们如何用他们了。
-
-
-
- 二、内部实现。
-
- (1)、第一次向链表中插入。此时链表中节点为null,第一次插入,无非就是把节点头插入而已。
-
- 可以看出就是把链表头初始化了,并且链表大小涨1。其中modCount记录整个链表修改的次数,链表的增加和删除它都会增加。毕竟第一次插入相对外调用是透明的,所以应该是私有的咯。(透明就是不可见,这里只得是外部没必要知道它的存在)
-
- Java代码
- private void addFirst(E e){
- head=new Entry<E>(e,null);
- size++;
- modCount++;
- }
-
- private void addFirst(E e){
- head=new Entry<E>(e,null);
- size++;
- modCount++;
- }
-
- (2)、表头插入。在链表的头前插入一个元素,新增的元素变成新的表头。这个插入是效率最高的,毕竟你时刻知道链表的头在哪里。
-
- Java代码
- public void addHead(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- Entry<E> newEntry=new Entry<E>(e,head);
- head=newEntry;
- size++;
- modCount++;
- }
- }
-
- public void addHead(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- Entry<E> newEntry=new Entry<E>(e,head);
- head=newEntry;
- size++;
- modCount++;
- }
- }可以看出头为null的时候,则表明链表中没值,只需调用第一次插入。否则对给定的元素创新增一个节点,新增节点的下一个指向头节点,当然此时自己已经变成头结点了,索引要更新头节点的引用。(可以看出想要清空链表,只需要将头置为null就好了)
-
-
-
- (3)、指定节点插入(插队)。在链表的指定节点插入一个元素,效率非常低。由于规则上你只能从队伍第一个开始往后找,找到你要插队位置的前一个,并将你插入其中,你先要告诉你身前人你在他身后,并且你自己要清楚你身后是谁。反正够麻烦的。
-
-
- Java代码
- public void addSpecifyIndex(E e,int index){
- if(index<0||index>size||size==0){
- throw new NoSuchElementException();
- }
- if(index==0){
- this.addHead(e);
- return;
- }
- int count=0;
- for (Entry<E> p=head; p!=null;p=p.nextEntry) {
- if(count+1==index){
- Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
- p.nextEntry=newEntry;
- size++;
- modCount++;
- return;
- }
- count++;
- }
- }
-
- public void addSpecifyIndex(E e,int index){
- if(index<0||index>size||size==0){
- throw new NoSuchElementException();
- }
- if(index==0){
- this.addHead(e);
- return;
- }
- int count=0;
- for (Entry<E> p=head; p!=null;p=p.nextEntry) {
- if(count+1==index){
- Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
- p.nextEntry=newEntry;
- size++;
- modCount++;
- return;
- }
- count++;
- }
- }
- Java代码
-
-
- 先进行判断index是否正确,规定不能插入null链表。而且不能跳着走,毕竟链表要连起来。由于要找到前一个,但是表头的前一个是没有的,所以index==0时要单独判断。后面则用count进行计数,找到其index-1节点,然后进行插队处理。
-
-
-
- (4)、尾插入。其实也是插队了,只是总是需要插到最后一个之后。
-
- Java代码
- public void add(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- this.addSpecifyIndex(e, size);
- }
- }
-
- public void add(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- this.addSpecifyIndex(e, size);
- }
- }
-
- (5)、指定节点获取元素。效率低,同样从头开始找到指定的节点把其中元素取出
-
-
- Java代码
- public E get(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- E result=null;
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- result=p.e;
- }
- count++;
- }
- return result;
- }
-
- public E get(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- E result=null;
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- result=p.e;
- }
- count++;
- }
- return result;
- }
- Java代码
-
-
-
-
- (6)、指定节点删除。效率低,同样需要找到指定节点前一节点,直接把指定节点跳过就好了。
-
- Java代码
- public void remove(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- if(index==0){
- head=head.nextEntry;
- size--;
- modCount++;
- return;
- }
- int count=0;
- for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
- if(count+1==index){
- p.nextEntry=p.nextEntry.nextEntry;
- size--;
- modCount++;
- break;
- }
- count++;
- }
- }
-
- public void remove(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- if(index==0){
- head=head.nextEntry;
- size--;
- modCount++;
- return;
- }
- int count=0;
- for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
- if(count+1==index){
- p.nextEntry=p.nextEntry.nextEntry;
- size--;
- modCount++;
- break;
- }
- count++;
- }
- }
-
- (7)、循环。为了好进行遍历演示,下面的就是循环遍历所用的了,大家随意看一下就好了。
-
-
-
- Java代码
- private transient Entry<E> current;
-
- public void setCursor(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- current=p;
- break;
- }
- count++;
- }
- }
-
- public boolean hasNext(){
- return current!=null;
- }
-
- public E next(){
- E result=current.e;
- current=current.nextEntry;
- return result;
- }
-
- private transient Entry<E> current;
-
- public void setCursor(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- current=p;
- break;
- }
- count++;
- }
- }
-
- public boolean hasNext(){
- return current!=null;
- }
-
- public E next(){
- E result=current.e;
- current=current.nextEntry;
- return result;
- }
-
- 三、测试。。一个main方法,测试一下。
-
- Java代码
- public static void main(String[] args) {
- SingleChain<String> singleChain=new SingleChain<String>();
- for (int i = 0; i < 4; i++) {
- singleChain.add(i+"");
- }
- //头插入
- // singleChain.addHead("head");
- //尾插入
- // singleChain.add("tail");
- //指定节点插入
- // singleChain.addSpecifyIndex("Specify", 1);
- //指定节点删除
- // singleChain.remove(3);
- //设置循环的初始节点
- singleChain.setCursor(0);
- int count=0;
- System.out.println("######SIZE"+singleChain.size()+"#######");
- while(singleChain.hasNext()){
- System.out.println("index:"+count+",entry:"+singleChain.next());
- count++;
- }
-
- System.out.println(singleChain.get(singleChain.size()-1));
- }
-
- public static void main(String[] args) {
- SingleChain<String> singleChain=new SingleChain<String>();
- for (int i = 0; i < 4; i++) {
- singleChain.add(i+"");
- }
- //头插入
- // singleChain.addHead("head");
- //尾插入
- // singleChain.add("tail");
- //指定节点插入
- // singleChain.addSpecifyIndex("Specify", 1);
- //指定节点删除
- // singleChain.remove(3);
- //设置循环的初始节点
- singleChain.setCursor(0);
- int count=0;
- System.out.println("######SIZE"+singleChain.size()+"#######");
- while(singleChain.hasNext()){
- System.out.println("index:"+count+",entry:"+singleChain.next());
- count++;
- }
-
- System.out.println(singleChain.get(singleChain.size()-1));
- }
-
-
-
- 四、全部代码
-
-
-
- Java代码
- package paladin.chain;
-
- import java.util.NoSuchElementException;
-
- public class SingleChain<E> implements Chain<E>{
-
- private Entry<E> head;
-
- private transient Entry<E> current;
-
- private int size;
-
- private int modCount;
-
-
- private void addFirst(E e){
- head=new Entry<E>(e,null);
- size++;
- modCount++;
- }
-
- public void addHead(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- Entry<E> newEntry=new Entry<E>(e,head);
- head=newEntry;
- size++;
- modCount++;
- }
- }
-
- public void addSpecifyIndex(E e,int index){
- if(index<0||index>size||size==0){
- throw new NoSuchElementException();
- }
- if(index==0){
- this.addHead(e);
- return;
- }
- int count=0;
- for (Entry<E> p=head; p!=null;p=p.nextEntry) {
- if(count+1==index){
- Entry<E> newEntry=new Entry<E>(e,p.nextEntry);
- p.nextEntry=newEntry;
- size++;
- modCount++;
- return;
- }
- count++;
- }
- }
-
- public void add(E e){
- if(head==null){
- this.addFirst(e);
- }else{
- this.addSpecifyIndex(e, size);
- }
- }
-
- public E get(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- E result=null;
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- result=p.e;
- }
- count++;
- }
- return result;
- }
-
- public void remove(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- if(index==0){
- head=head.nextEntry;
- size--;
- modCount++;
- return;
- }
- int count=0;
- for (Entry<E> p=head;p.nextEntry!=null;p=p.nextEntry) {
- if(count+1==index){
- p.nextEntry=p.nextEntry.nextEntry;
- size--;
- modCount++;
- break;
- }
- count++;
- }
- }
-
- public void setCursor(int index){
- if(index<0||index>=size){
- throw new NoSuchElementException();
- }
- int count=0;
- for (Entry<E> p=head;p!=null;p=p.nextEntry) {
- if(count==index){
- current=p;
- break;
- }
- count++;
- }
- }
-
- public boolean hasNext(){
- return current!=null;
- }
-
- public E next(){
- E result=current.e;
- current=current.nextEntry;
- return result;
- }
-
- public int size(){
- return this.size;
- }
-
- public static void main(String[] args) {
- SingleChain<String> singleChain=new SingleChain<String>();
- for (int i = 0; i < 4; i++) {
- singleChain.add(i+"");
- }
- //头插入
- // singleChain.addHead("head");
- //尾插入
- // singleChain.add("tail");
- //指定节点插入
- // singleChain.addSpecifyIndex("Specify", 1);
- //指定节点删除
- // singleChain.remove(3);
- //设置循环的初始节点
- singleChain.setCursor(0);
- int count=0;
- System.out.println("######SIZE"+singleChain.size()+"#######");
- while(singleChain.hasNext()){
- System.out.println("index:"+count+",entry:"+singleChain.next());
- count++;
- }
-
- System.out.println(singleChain.get(singleChain.size()-1));
- }
-
- private static class Entry<E>{
- E e;
- Entry<E> nextEntry;
-
- public Entry(E e,Entry<E> nextEntry){
- this.e=e;
- this.nextEntry=nextEntry;
- }
- }
- }
-
相关阅读:
Code Reading chap2
Code Reading chap4
Code Reading chap6
常用的一些sql基础语句汇总
20170322、Linux常用命令汇总
在windows上部署使用Redis
20170322、php基础语法
20170822、在Linux上部署使用Redis
Linux安装配置SVN服务器
Linux安装配置MySQL
-
原文地址:https://www.cnblogs.com/xingege/p/4074039.html
Copyright © 2020-2023
润新知