——看破楼外楼,历经园中园
写出数据结构系列的文章,目的还是明确各种数据结构的实现逻辑,
然后根据逻辑我们自定义对应的类,并加以使用,实现的功能大同小异;
主要还是
1.结构的生成;2.结构的销毁;3.在结构中查找满足规定条件的数据元素;
4.在结构中插入新的数据元素;5.删除结构中已经存在的数据元素;6.遍历。
之后同系列的文章也会按照这个逻辑写下去了。
一、链表在使用场景的引入
在讲述链表之前,我们可以先回顾最为熟悉的数组,
数组是连续存储,大小固定,按序访问的数据结构。
由于数组空间的固定,我们时常会面临内存空间浪费或越界的情况
当数据数量巨大(huge)的时候,进行相关的挪位操作是十分没有效率的;
操作的繁琐性是由于数组在分布内存时的连续性造成的,
为了降低繁琐性,应该有不连续的数据结构用来储存数据,
不同单位之间可以不连续分布,但是相互之间又有一定的联系;
链表就是这么一种满足上述要求的数据结构:)
二、链表的组成
* 基本组成单位:节点(Node)
节点的组成
节点由两个部分组成:
- 数据域:用来储存相关数据,当然你可以用Object来定义属性。
- 引用域:用来储存有相关联系的节点。
- 单向链表:储存下一个节点;
- 双向链表:储存上一个节点与下一个节点;
### 节点的定义代码
package MylinkenList;
public class Node {
private Object e;
private Node next;
public Node(Object e)
{
this.e=e;
}
public Node( )
{
}
public Object Obejct()
{
return e;
}
public Node next()
{
return next;
}
public void setNode(Node n)
{
next=n;
}
}
*单向链表组成
- Size:纪录该链表的长度,进行增添删除时会与传入的索引发生比较,同时改变自身的值;
- Head(Node): 空节点,用来标志一个链表的开始,遍历时也会使用该节点;
- Tail(Node):空节点,开始指向头部;按顺序最新添加的节点的下一节点指向该点;
链表定义的代码
public class myLinkedList {
public Node Head;
public Node Tail;
public int size;
public myLinkedList() {
Head = new Node();
Tail = new Node();
Head.setnext(Tail);
size = 0;
}
}
三、链表功能的实现
* 前置准备的思考
首先,我们要先考虑方法的返回值:
- 插入的时候,返回布尔变量true,表示成功;
- 替换的时候,返回被替代的节点的数据;
- 删除的时候,返回被删除的节点的数据;
接着,我们要先考虑方法的传入:
- 插入/ 替换的时候,传入index和obejct;
- 删除的时候,传入index;
接着我们要写一段用于判断索引值是否合法的语句,
加在所以方法的最前端:
if(index<0||index>=size)
{
System.out.println("The Index is error!")
return 0;
}
* 操作位置的考虑
首先呢,无论哪个位置,本质上还是在调整某些节点指向的节点;
而替换并不会有情况上的差异;
- 添加
- 添加的节点在首位
- 头节点的next指向新节点;
- 新节点的next指向头节点的next;
- 添加的节点在尾部;
- 指定节点的next指向新节点;
- 新节点的next指向尾节点;
- 添加的节点在中间;
- 指定节点的上一个节点的next指向新节点;
- 新节点的next指向指定节点;
- 删除
- 删除的节点在首位
- 头节点的next指向指定节点的next;
- 指定节点的next指向null;
- 删除的节点在尾部
- 指定节点的前一个节点的next指向尾节点;
- 指定节点的next指向null;
- 删除的节点在中间
- 指定节点的前一个节点的next指向指定节点的next;
- 指定节点的next指向null;
- 替换
- 替换的节点在首位
- 头节点的next指向新节点;
- 新节点的next指向指定节点的next;
- 指定节点的next指向null;
- 替换的节点在尾部
- 指定节点的上一个节点的next指向新节点;
- 新节点的next指向尾节点;
- 指定节点的next指向null;
- 替换的节点在尾部
- 指定节点的上一个节点的next指向新节点;
- 新节点的next指向指定节点的下一个节点;
- 指定节点的next指向null;
嗯…如果你和我一样是初学者,建议你还是拿张纸画画,这样会更好理解呀。JDK一览:
2019.2.22:
1.实现了JDK中大部分?的方法.
2.仍未实现的方法
- clone()
- pop()
- toArray()
- toArray(T[] a)
* 实现的代码
package Mylinkedlist;
import Myarraylist.MyArrayList;
public class MyLinkedlist<E> {
public String name;
public Node head;
public Node tail;
public int size=0;
public MyLinkedlist(String name) {
this.name=name;
head=new Node();
tail=new Node();
head.nextNode=tail;
tail.nextNode=null;
}
public boolean add(E e)
{
Node newNode=new Node();
newNode.data=e;
if(size==0)
{
head.nextNode=newNode;
}
else
{
Node lastNode=new Node();
lastNode=head.nextNode;
for(int i=0;i<size-1;i++)
{
lastNode=lastNode.nextNode;
}
lastNode.nextNode=newNode;
}
newNode.nextNode=null;
tail=newNode;
size++;
return true;
}
public void add(int index,E e)
{
if(index<0||index>size)
{
System.out.println("error");
}
else
{
Node newNode=new Node();
newNode.data=e;
if(size==0)
{
head.nextNode=newNode;
}
else
{
Node lastNode=new Node();
lastNode=head.nextNode;
for(int i=0;i<index-1;i++)
{
lastNode=lastNode.nextNode;
}
newNode.nextNode=lastNode.nextNode;
lastNode.nextNode=newNode;
}
size++;
}
if(index==size)
{
add(e);
}
}
public void addFirst(E e)
{
if(size>0)
{
Node newNode=new Node();
newNode.data=e;
newNode.nextNode=head.nextNode;
head.nextNode=newNode;
size++;
}
}
public void addLast(E e)
{
Node newNode=new Node();
newNode.data=e;
if(size==0)
{
head.nextNode=newNode;
}
else
{
Node lastNode=new Node();
lastNode=head.nextNode;
for(int i=0;i<size-1;i++)
{
lastNode=lastNode.nextNode;
}
lastNode.nextNode=newNode;
}
newNode.nextNode=null;
tail=newNode;
size++;
}
public void clear()
{
head.nextNode=null;
size=0;
}
public boolean contains(Object o)
{
boolean a=false;
Node Node=head.nextNode;
for(int i=0;i<size;i++)
{
a=(o==null ? Node.data==null : o.equals(Node.data));
if(a==true)
{
return a;
}
Node=Node.nextNode;
}
return a;
}
public void descending()
{
if(size<2)
{
System.out.println("error");
}
else
{
Node a=head.nextNode;
Node b=a.nextNode;
Node c=b.nextNode;
tail=a;
b.nextNode=a;
a.nextNode=null;
if(size==2)
{
head.nextNode=b;
}
else
{ while(c!=null)
{
b.nextNode=a;
a=b;
b=c;
c=c.nextNode;
}
b.nextNode=a;
head.nextNode=b;
}
}
}
public int indexOf(Object o)
{
Node Node=head.nextNode;
for(int i=0;i<size;i++)
{
if(o.equals(Node.data))
{
return i;
}
Node=Node.nextNode;
}
return -1;
}
public int lastIndexOf(Object o)
{
Node Node=head.nextNode;
int a=-1;
for(int i=0;i<size;i++)
{
if(o.equals(Node.data))
{
a=i;
}
Node=Node.nextNode;
}
return a;
}
public E element()
{
return (E)head;
}
public E get(int index)
{
if(index<0||index>size)
{
System.out.println("error");
return null;
}
else
{
Node get=head.nextNode;
for(int i=0;i<index;i++)
{
get=get.nextNode;
}
return (E)get.data;
}
}
public E getFirst()
{
if(size==0)
{
System.out.println("error");
return (E)null;
}
else
{
Node a=head.nextNode;
return (E)a.data;
}
}
public E getLast()
{
if(size==0)
{
System.out.println("error");
return (E)null;
}
else
{
Node a=tail;
return (E)a.data;
}
}
public E peekFirst()
{
if(size==0)
{
System.out.println("error");
return (E)null;
}
else
{
return (E)head.nextNode.data;
}
}
public E peekLast()
{
if(size==0)
{
System.out.println("error");
return (E)null;
}
else
{
return (E)tail.data;
}
}
public int size()
{
return size;
}
public E remove(int index)
{
if(index<0||index>=size)
{
System.out.println("error");
return (E)null;
}
else
{ Node a=head.nextNode;
if(index==0)
{
head.nextNode=a.nextNode;
a.nextNode=null;
size--;
return (E)a.data;
}
else
{
for(int i=0;i<index-1;i++)
{
a=a.nextNode;
}
if(index==size-1)
{
tail=a;
}
Node b=a.nextNode;
a.nextNode=b.nextNode;
b.nextNode=null;
size--;
return (E)b.data;
}
}
}
public boolean remove(Object o)
{
for(int i=0;i<size;i++)
{
if(o==null?get(i)==null:o.equals(get(i)))
{
remove(i);
return true;
}
}
return false;
}
public E removeFirst()
{
return remove(0);
}
public E removeLast()
{
return remove(size-1);
}
public boolean removeFirstOccurrence(Object o)
{
Node Node=head.nextNode;
Node LNode=head;
for(int i=0;i<size;i++)
{
if(o.equals(Node.data))
{
LNode.nextNode=Node.nextNode;
Node.nextNode=null;
size--;
return true;
}
Node=Node.nextNode;
LNode=LNode.nextNode;
}
return false;
}
public boolean removeLastOccurrence(Object o)
{
if(remove(lastIndexOf(o))!=null)
{
return true;
}
return false;
}
public E set(int index,E e)
{
add(index,e);
return remove(index+1);
}
public boolean addAll(MyLinkedlist a)
{
Node newNode=a.head.nextNode;
if(size==0)
{
head.nextNode=newNode;
}
else
{
Node lastNode=new Node();
lastNode=head.nextNode;
for(int i=0;i<size-1;i++)
{
lastNode=lastNode.nextNode;
}
lastNode.nextNode=newNode;
}
tail=a.tail;
size+=a.size;
return true;
}
public boolean addAll(MyLinkedlist a,int index)
{
if(index<0||index>size)
{
System.out.println("error");
}
else if(a.size!=0)
{
Node newNode=a.head.nextNode;
if(size==0)
{
head.nextNode=newNode;
tail=a.tail;
}
else if(index==size)
{
addAll(a);
}
else
{
Node lastNode=head.nextNode;
for(int i=0;i<index-1;i++)
{
lastNode=lastNode.nextNode;
}
a.tail.nextNode=lastNode.nextNode;
lastNode.nextNode=newNode;
}
size+=a.size;
}
return true;
}
public void toMyString()
{
System.out.println("name:"+name+" size:"+size);
if(size==0)
{
System.out.println("空序列");
System.out.println();
}
else
{
Node nowNode=head.nextNode;
for(int i=0;i<size;i++)
{
System.out.print("第"+i+"位:"+nowNode.data+" ");
if(i%7==0&&i!=0)System.out.println();
nowNode=nowNode.nextNode;
}
System.out.println();
System.out.println();
}
}
public static void main(String [] args)
{
MyLinkedlist a=new MyLinkedlist("a");
MyLinkedlist b=new MyLinkedlist("b");
MyLinkedlist c=new MyLinkedlist("c");
for(int i=0;i<5;i++)
{
a.add(i*3);
c.add(i*4);
}
b.add(0, 1);
a.toMyString();
b.toMyString();
c.toMyString();
System.out.println("————————————————————————add:");
a.add(1, 1);
b.add(1, 2);
a.toMyString();
b.toMyString();
System.out.println("————————————————————————addAll:");
a.addAll(b);
a.toMyString();
a.addAll(c,2);
a.toMyString();
System.out.println("————————————————————————addFirst:");
a.addFirst(15);
a.toMyString();
System.out.println("————————————————————————addLast:");
a.addLast(25);
a.toMyString();
System.out.println("————————————————————————clear:");
b.clear();
b.toMyString();
System.out.println("————————————————————————contains(1):");
System.out.println(a.contains(1));
System.out.println("————————————————————————contains(null):");
System.out.println(a.contains(null));
System.out.println("————————————————————————descending(反转单向链表):");
a.descending();
a.toMyString();
System.out.println("————————————————————————get:");
System.out.println(a.get(2));
System.out.println("————————————————————————getFirst:");
System.out.println(a.getFirst());
System.out.println("————————————————————————getLast:");
System.out.println(a.getLast());
System.out.println("————————————————————————size:");
System.out.println(a.size());
System.out.println("————————————————————————indexOf:");
System.out.println(a.indexOf(1));
System.out.println("————————————————————————lastIndexOf:");
System.out.println(a.lastIndexOf(1));
a.toMyString();
System.out.println("————————————————————————remove:");
System.out.println(a.remove(2));
a.toMyString();
System.out.println("————————————————————————remove(object):");
int numa=2;
System.out.println(a.remove((Object)numa));
a.toMyString();
System.out.println("————————————————————————removeFirst :");
System.out.println(a.removeFirst());
a.toMyString();
System.out.println("————————————————————————removeLast :");
System.out.println(a.removeLast());
a.toMyString();
System.out.println("————————————————————————removeFirstOccurrence :");
int numb=0;
System.out.println(a.removeFirstOccurrence(numb));
a.toMyString();
System.out.println("————————————————————————removeLastOccurrence :");
System.out.println(a.removeFirstOccurrence(numb));
a.toMyString();
System.out.println("————————————————————————set :");
System.out.println(a.set(3,5));
a.toMyString();
}
}
Node类
package Mylinkedlist;
public class Node {
public Node nextNode=null;
public Object data=null;
public Node() {}
public void next(Node n)
{
nextNode=n;
}
public void delelte()
{
nextNode=null;
}
}
运行结果:
name:a size:5
第0位:0 第1位:3 第2位:6 第3位:9 第4位:12
name:b size:1
第0位:1
name:c size:5
第0位:0 第1位:4 第2位:8 第3位:12 第4位:16
————————————————————————add:
name:a size:6
第0位:0 第1位:1 第2位:3 第3位:6 第4位:9 第5位:12
name:b size:2
第0位:1 第1位:2
————————————————————————addAll:
name:a size:8
第0位:0 第1位:1 第2位:3 第3位:6 第4位:9 第5位:12 第6位:1 第7位:2
name:a size:13
第0位:0 第1位:1 第2位:0 第3位:4 第4位:8 第5位:12 第6位:16 第7位:3
第8位:6 第9位:9 第10位:12 第11位:1 第12位:2
————————————————————————addFirst:
name:a size:14
第0位:15 第1位:0 第2位:1 第3位:0 第4位:4 第5位:8 第6位:12 第7位:16
第8位:3 第9位:6 第10位:9 第11位:12 第12位:1 第13位:2
————————————————————————addLast:
name:a size:15
第0位:15 第1位:0 第2位:1 第3位:0 第4位:4 第5位:8 第6位:12 第7位:16
第8位:3 第9位:6 第10位:9 第11位:12 第12位:1 第13位:2 第14位:25
————————————————————————clear:
name:b size:0
空序列
————————————————————————contains(1):
true
————————————————————————contains(null):
false
————————————————————————descending(反转单向链表):
name:a size:15
第0位:25 第1位:2 第2位:1 第3位:12 第4位:9 第5位:6 第6位:3 第7位:16
第8位:12 第9位:8 第10位:4 第11位:0 第12位:1 第13位:0 第14位:15
————————————————————————get:
1
————————————————————————getFirst:
25
————————————————————————getLast:
15
————————————————————————size:
15
————————————————————————indexOf:
2
————————————————————————lastIndexOf:
12
name:a size:15
第0位:25 第1位:2 第2位:1 第3位:12 第4位:9 第5位:6 第6位:3 第7位:16
第8位:12 第9位:8 第10位:4 第11位:0 第12位:1 第13位:0 第14位:15
————————————————————————remove:
1
name:a size:14
第0位:25 第1位:2 第2位:12 第3位:9 第4位:6 第5位:3 第6位:16 第7位:12
第8位:8 第9位:4 第10位:0 第11位:1 第12位:0 第13位:15
————————————————————————remove(object):
true
name:a size:13
第0位:25 第1位:12 第2位:9 第3位:6 第4位:3 第5位:16 第6位:12 第7位:8
第8位:4 第9位:0 第10位:1 第11位:0 第12位:15
————————————————————————removeFirst :
25
name:a size:12
第0位:12 第1位:9 第2位:6 第3位:3 第4位:16 第5位:12 第6位:8 第7位:4
第8位:0 第9位:1 第10位:0 第11位:15
————————————————————————removeLast :
15
name:a size:11
第0位:12 第1位:9 第2位:6 第3位:3 第4位:16 第5位:12 第6位:8 第7位:4
第8位:0 第9位:1 第10位:0
————————————————————————removeFirstOccurrence :
true
name:a size:10
第0位:12 第1位:9 第2位:6 第3位:3 第4位:16 第5位:12 第6位:8 第7位:4
第8位:1 第9位:0
————————————————————————removeLastOccurrence :
true
name:a size:9
第0位:12 第1位:9 第2位:6 第3位:3 第4位:16 第5位:12 第6位:8 第7位:4
第8位:1
————————————————————————set :
3
name:a size:9
第0位:12 第1位:9 第2位:6 第3位:5 第4位:16 第5位:12 第6位:8 第7位:4
第8位:1