[单向链表与双向链表的实现]
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[单向链表与双向链表的实现]相关的知识,希望对你有一定的参考价值。
学过Java基础集合的话,就知道链表啊;它增删比较快,查询较慢;
它是物理存储单元上非连续、非顺序的存储结构
比如我要给这个链表的14和6之间增加新节点56
;将预备添加位置的前一个结点指针指向到它即可;
那么这里准备删除节点节点8呢,操作差不多,指针指向调整一下,它就完美脱离链表了;
链表这块的话,其实就是在操作它的指针指向;不要觉得非常难哦
单向链表
每个结点都由数据域和指针域组成,头结点的数据域不存储数据,
数据域:真实存储数据,指针域:存储后继结点。
package com.xiaozhi.day03linkedlist;
import java.util.Iterator;
/**
* @author by @CSDN 小智RE0
* @date 2021-12-21 17:20
* 单向链表;
*/
//为达到遍历,Iterable接口
public class OneDirectionLinked<T> implements Iterable<T>
//链表的节点;
class ListNode
//节点元素;
T data;
//下一个;
ListNode next;
//初始化;
public ListNode(T data, ListNode next)
this.data = data;
this.next = next;
//头结点;
ListNode head;
//节点个数;
int size;
//初始化;
public OneDirectionLinked()
this.head = new ListNode(null, null);
this.size = 0;
//判断是否为空;
public boolean isEmpty()
return this.size == 0;
//链表长度;
public int getLength()
return this.size;
//清空链表;
public void clearList()
//将头结点下一个节点置为空;
head.next = null;
size = 0;
//获取指定位置的元素;
public T findDataByIndex(int index)
ListNode node = head.next;
for (int i = 0; i < index; i++)
node = node.next;
return node.data;
//尾部添加节点;
public void addNodeLast(T ele)
//首先找到尾部;
ListNode ope = head;
while (ope.next != null)
ope = ope.next;
//然后创建新节点;
ListNode newNode = new ListNode(ele, null);
//接到尾部;
ope.next = newNode;
//长度递增;
this.size += 1;
//指定位置添加节点;
public void addNodeByPosition(int po, T ele)
//先找到这个指定位置的前一个位置;
ListNode opNode = head;
for (int i = 0; i <= po - 1; i++)
opNode = opNode.next;
//新节点将会挂接到这个操作结点下一个节点的后面;
ListNode insertNext = opNode.next;
//新节点接到他前面位置的节点即可;
ListNode newNode = new ListNode(ele, insertNext);
opNode.next = newNode;
this.size++;
//删除指定位置的节点;且返回这个结点值;
public T removeNodeByPosition(int po)
//同样,首先找到这个待删除结点的前一个位置结点;
ListNode opNode = head;
for (int i = 0; i <= po - 1; i++)
opNode = opNode.next;
//删除节点;
ListNode removeNode = opNode.next;
//删除节点的后一个结点;
ListNode removeNext = removeNode.next;
opNode.next = removeNext;
this.size--;
return removeNode.data;
//查询第一个出现的节点位置;若没有就返回-1;
public int getNodeIndexOf(T ele)
ListNode opNode = head;
//遍历链表,
for (int index = 0; opNode.next != null; index++)
opNode = opNode.next;
if (opNode.data.equals(ele))
return index;
return -1;
//遍历的方法;
@Override
public Iterator<T> iterator()
return new MyIterator();
//定义一个内部类实现迭代接口;
public class MyIterator implements Iterator<T>
ListNode node;
//初始化;
public MyIterator()
this.node = head;
//是否有下一个节点;
@Override
public boolean hasNext()
return this.node.next != null;
//得到下一个节点的值;
@Override
public T next()
node = node.next;
return node.data;
测试使用
package com.xiaozhi.day03linkedlist;
/**
* @author by @CSDN 小智RE0
* @date 2021-12-21 19:37
*/
public class Test
//测试
public static void main(String[] args)
OneDirectionLinked<Integer> one = new OneDirectionLinked<>();
//添加元素;
one.addNodeLast(12);
one.addNodeLast(13);
one.addNodeLast(12);
one.addNodeLast(14);
one.addNodeLast(15);
one.addNodeLast(16);
//指定位置添加元素
one.addNodeByPosition(2,123);
//遍历;
one.iterator().forEachRemaining(a-> System.out.print(a +"->"));
System.out.println();
//删除指定位置的元素;
System.out.println("删除指定位置元素:"+one.removeNodeByPosition(4));
one.iterator().forEachRemaining(a-> System.out.print(a +"->"));
System.out.println();
System.out.println("123第一次出现的位置:"+one.getNodeIndexOf(123));
测试结果
12->13->123->12->14->15->16->
删除指定位置元素:14
12->13->123->12->15->16->
123第一次出现的位置:2
双向链表
package com.xiaozhi.day03linkedlist.twodirection;
import java.util.Iterator;
/**
* @author by @CSDN 小智RE0
* @date 2021-12-21 20:32
* 双向链表
*/
public class DoubleDirectionLinked<T> implements Iterable<T>
//节点类;
class ListNode
//节点数据;
T data;
//前置指针;
ListNode pre;
//后置指针;
ListNode next;
//初始化;
public ListNode(T data, ListNode pre, ListNode next)
this.data = data;
this.pre = pre;
this.next = next;
//头结点;不存储数据;
ListNode head;
//尾节点;
ListNode tail;
//节点的个数;
int size;
//初始化链表;
public DoubleDirectionLinked()
this.head = new ListNode(null, null, null);
this.tail = null;
this.size = 0;
//获取链表的长度;
public int getLength()
return this.size;
//判断链表是否为空;
public boolean isEmpty()
return this.size == 0;
//清空链表;
public void clearList()
this.head.pre = null;
this.head.next = null;
this.tail = null;
this.size = 0;
//尾部添加新节点;
public void addNodeToLast(T ele)
if (isEmpty())
//若链表为空,直接让挂接到头结点后即可;
ListNode node = new ListNode(ele, head, null);
this.tail = node;
this.head.next = tail;
else
ListNode initTail = this.tail;
//直接挂接到尾节点;
ListNode node = new ListNode(ele, initTail, null);
initTail.next = node;
tail = node;
this.size += 1;
//指定位置添加新节点;
public void addNodeByPosition(int po, T ele)
//首先找到前一个位置的节点;以及当前需要添加节点的位置;
ListNode preNode = head;
for (int i = 0; i < po; i++)
preNode = preNode.next;
//要添加的位置;
ListNode curNode = preNode.next;
//要添加的新节点;
ListNode node = new ListNode(ele, preNode, curNode);
preNode.next = node;
curNode.pre = node;
this.size += 1;
//获取链表第一个节点;
public T getFirst()
if (isEmpty()) return null;
return head.next.data;
//获取末尾节点;
public T getLast()
if (isEmpty()) return null;
return this.tail.data;
//查询指定位置的元素;
public T getDataByIndex(int index)
ListNode opNode = head.next;
for (int i = 0; i < index; i++)
opNode = opNode.next;
return opNode.data;
//查询到节点在链表中第一次出现的位置;找不到则返回-1;
public int getPositionByData(T ele)
ListNode node = head;
for (int i = 0; node != null; i++)
node = node.next;
if (node.data.equals(ele))
return i;
return -1;
//删除指定位置的元素;
public T removeDataByIndex(int index)
//找到删除元素的前一个位置结点;
ListNode preNode = head;
for (int i = 0; i < index; i++)
preNode = preNode.next;
//需要删除的节点;
ListNode curNode = preNode.next;
//待删除结点的下一个节点;
ListNode nextNode = curNode.next;
//更改指向关系;
preNode.next = nextNode;
nextNode.pre = preNode;
//元素个数减少;
this.size -= 1;
return curNode.data;
//实现链表的遍历;
@Override
public Iterator<T> iterator()
return new MyIterator();
//使用自定义内部类完成迭代器功能;
class MyIterator implements Iterator
private ListNode node;
//初始化;
public MyIterator()
this.node = head;
//判断是否还有下一个元素;
@Override
public boolean hasNext()
return node.next != null;
//得到下一个元素;
@Override
public Object next()
node = node.next;
return node.data;
测试
public class Test
//测试
public static void main(String[] args)
DoubleDirectionLinked<Integer> dou= new DoubleDirectionLinked<>();
//添加元素;
dou.addNodeToLast(12);
dou.addNodeToLast(13);
dou.addNodeToLast(12);
dou.addNodeToLast(14);
dou.addNodeToLast(15);
dou.addNodeToLast(16);
//指定位置添加元素
dou.addNodeByPosition(2,123);
//遍历;
dou.iterator().forEachRemaining(a-> System.out.print(a +"->"));
System.out.println();
//删除指定位置的元素;
System.out.println("删除指定位置元素:"+dou.removeDataByIndex(4));
dou.iterator().forEachRemaining(a-> System.out.print(a +"->"));
System.out.println();
System.out.println("123第一次出现的位置:"+dou.getPositionByData(123));
System.out.println("获取第一个元素-->"+dou.getFirst());
System.out.println("获取第一个元素-->"+dou.getLast());
测试结果
12->13->123->12->14->15->16->
删除指定位置元素:14
12->13->123->12->15->16->
123第一次出现的位置:2
获取第一个元素-->12
获取第一个元素-->16
以上是关于[单向链表与双向链表的实现]的主要内容,如果未能解决你的问题,请参考以下文章