单链表 java_Java实现单链表

真正的动态数据结构(引用和指针)

优点:真正的动态,不需要处理固定容量的问题。

缺点:丧失随机访问的能力。

链表就像寻宝,我们拿到藏宝图开始出发寻宝,每找到一个地方后,里面藏着下一步应该去哪里寻找。一步一步往下找,就能找到宝藏。每个节点都存有数据和下个节点的位置。

d3795fa1b87c02226ce8d5e6577eca55.png

将数据存储在节点中,next指向当前节点的下一个节点。

classNode

{

E e;

Node next;

}

要想访问这个链表的所有节点,我们必须知道链表的头节点,所以我们定义head,在定义个size记录链表中有几个元素

19a6248ca210355da20b311c2f503dbd.png

向链表的头添加元素很简单,我们添加一个node,在把这个nodet指针指下一个节点,这时的head节点就变成我们添加的节点,我们就变成头节点。

572adcadafdccdd92e0edbec7278a81c.png

所以LinkList类

packagecom.dsideal.test;public class LinkList{private classNode

{publicE e;publicNode next;publicNode(E e, Node next)

{this.e =e;this.next =next;

}publicNode(E e)

{this(e,null);

}publicNode()

{this(null,null);

}

@OverridepublicString toString()

{returne.toString();

}

}privateNode head;private intsize;publicLinkList()

{

head= null;

size= 0;

}public intgetSize()

{returnsize;

}public booleanisEmpty()

{return size == 0;

}public voidaddFirst(E e)

{//Node node = new Node(e);//node.next = head;//head = node;

head= newNode(e,head);

size++;

}

}

在链表中间添加元素,我们必须知道在插入节点之前的一个节点是什么。将前一个节点的指针指向我们插入的节点,把我们的插入节点的指针指向下一个节点。

9d4210ec8bab0d07d164b88d87d64848.png

packagecom.dsideal.test;public class LinkList{private classNode

{publicE e;publicNode next;publicNode(E e, Node next)

{this.e =e;this.next =next;

}publicNode(E e)

{this(e,null);

}publicNode()

{this(null,null);

}

@OverridepublicString toString()

{returne.toString();

}

}privateNode head;private intsize;publicLinkList()

{

head= null;

size= 0;

}public intgetSize()

{returnsize;

}public booleanisEmpty()

{return size == 0;

}public voidaddFirst(E e)

{//Node node = new Node(e);//node.next = head;//head = node;

head= newNode(e,head);

size++;

}public void add(intindex,E e)

{if (index < 0 || index >size)

{throw new IllegalArgumentException("add is fail,index < 0 or index >= size");

}if (index == 0)

{

addFirst(e);

}else{

Node prev=head;for (int i = 0;i < index - 1;++i)

{

prev=prev.next;

}//Node node = new Node(e);//node.next = prev.next;//prev.next = node;

prev.next= newNode(e,prev.next);

size++;

}

}public voidaddLast(E e)

{

add(size,e);

}

@OverridepublicString toString()

{

StringBuilder res= newStringBuilder();

res.append("Link head:");

Node cur=head;while (cur != null)

{

res.append(cur+ "->");

cur=cur.next;

}

res.append("NULL");returnres.toString();

}

}

这时我们发现,当add插入index等于零的时候,要做个判断。所以我们引入一个虚拟的头节点。Node dunmmy = new Node(null,null);删除节点,找到要删除节点的上一个节点,将

他的指针指向删除节点的下一个节点,将我们删除节点的next指向null。

cf15ca8af2e9772ae388583b3ed1e713.png

所以LinkLIst类变为

public class LinkList{private classNode

{publicE e;publicNode next;publicNode(E e, Node next)

{this.e =e;this.next =next;

}publicNode(E e)

{this(e, null);

}publicNode()

{this(null, null);

}

@OverridepublicString toString()

{returne.toString();

}

}privateNode dummyHead;private intsize;publicLinkList()

{

dummyHead= new Node(null, null);

size= 0;

}//获取链表元素个数

public intgetSize()

{returnsize;

}//链表是否为空

public booleanisEmpty()

{return size == 0;

}//增加链表头元素

public voidaddFirst(E e)

{//Node node = new Node(e);//node.next = head;//head = node;

add(0, e);

}//增加链表元素个数

public void add(intindex, E e)

{if (index < 0 || index >size)

{throw new IllegalArgumentException("index < 0 or index > size,add is fail.");

}

Node prev=dummyHead;for (int i = 0; i < index; i++)

{

prev=prev.next;

}//Node node = new Node(e);//node.next = prev.next;//prev.next = node;

prev.next = newNode(e, prev.next);

size++;

}//添加链表末尾元素

public voidaddLast(E e)

{

add(size, e);

}//获取元素index

public E get(intindex)

{if (index < 0 || index >=size)

{throw new IllegalArgumentException("get is fail,index < 0 or index > size");

}

Node cur=dummyHead.next;for (int i = 0;i < index;++i)

{

cur=cur.next;

}returncur.e;

}//获取第一个元素

publicE getFirst()

{return get(0);

}//获取最后一个元素

publicE getLast()

{return get(size - 1);

}//判读是否包含

public booleancontains(E e)

{

Node cur=dummyHead.next;while (cur != null)

{if(cur.e.equals(e))

{return true;

}

cur=cur.next;

}return false;

}//修改值

public void set(intindex,E e)

{if (index < 0 || index >=size)

{throw new IllegalArgumentException("set is fail,index < 0 or index > size");

}

Node cur=dummyHead.next;for (int i = 0;i < index;++i)

{

cur=cur.next;

}

cur.e=e;

}//删除元素

public E remove(intindex)

{if (index < 0 || index >=size)

{

}

Node prev=dummyHead;for (int i = 0;i < index;++i)

{

prev=prev.next;

}//删除的元素

Node retNode =prev.next;

prev.next=retNode.next;

retNode.next= null;//删除元素的指向下一个地址为空

size--;returnretNode.e;

}//删除第一元素

publicE removeFirst()

{return remove(0);

}//删除最后一个元素

publicE removeLast()

{return remove(size - 1);

}

@OverridepublicString toString()

{

StringBuilder res= new StringBuilder("");for (Node cur = dummyHead.next; cur != null; cur =cur.next)

{

res.append(cur+ "->");

}

res.append("NULL");returnres.toString();

}

}

用链表实现栈

public class LinkListStack implements Stack{private LinkListlinkList;publicLinkListStack()

{

linkList= new LinkList<>();

}

@Overridepublic intgetSize()

{returnlinkList.getSize();

}

@Overridepublic booleanisEmpty()

{returnlinkList.isEmpty();

}

@Overridepublic voidpush(E e)

{

linkList.addFirst(e);

}

@OverridepublicE pop()

{returnlinkList.removeFirst();

}

@OverridepublicE peek()

{returnlinkList.getFirst();

}

@OverridepublicString toString()

{

StringBuilder res= newStringBuilder();

res.append("Stack top[");

res.append(linkList);

res.append("] tail");returnres.toString();

}

}

链表实现队列,优化算法变为O(1)级别的

public class LinkListQueue implements Queue{//内置节点

private classNode

{publicE e;publicNode next;publicNode(E e,Node next)

{this.e =e;this.next =next;

}publicNode(E e)

{this(e,null);

}publicNode()

{this(null,null);

}

@OverridepublicString toString()

{returne.toString();

}

}privateNode head,tail;private intsize;publicLinkListQueue()

{

head= null;

tail= null;

size= 0;

}

@Overridepublic intgetSize() {returnsize;

}

@Overridepublic booleanisEmpty() {return size == 0;

}

@Overridepublic voidenqueue(E e) {if (tail == null)

{

tail= newNode(e);

head=tail;

}else{

tail.next= newNode(e);

tail=tail.next;

tail.next= null;

}

size++;

}

@OverridepublicE dequeue() {if(isEmpty())

{throw new IllegalArgumentException("dequeue is fail,queue is isEmpty");

}

Node retNode=head;

head=retNode.next;

retNode.next= null;if (head == null)

{

tail= null;

}

size--;returnretNode.e;

}

@OverridepublicE getFront() {if(isEmpty())

{throw new IllegalArgumentException("Queue is isEmpty,so getFront is fail.");

}returnhead.e;

}

@OverridepublicString toString()

{

StringBuffer str= new StringBuffer("");

str.append("LinkListQueue: head:");

Node cur=head;while (cur != null)

{

str.append(cur+ "->");

cur=cur.next;

}

str.append("NULL");returnstr.toString();

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值