java-----单链表
Posted 小鹿可可乐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java-----单链表相关的知识,希望对你有一定的参考价值。
单链表
1.单链表基本操作
链表是一个有序的列表
链表不同于数组,链表是以结点的形式存储,在物理空间上不一定连续
链表的每个结点的内部包含value(数据)域,next(指针)域,指针域指向下一个结点的位置
1.1代码
public class SingleLink<E extends Comparable<E>> implements List<E>
private Node<E> head;
private Node<E> tail;//尾部 尾插的时间复杂度O(1)
private int size;
public SingleLink()
this.head = null;//空链表
this.tail = null;
@Override
public void addHead(E value) //O(1)
Node<E> node = new Node<>(value);
if(head ==null && tail == null)
head = node;
tail = node;
else
//新节点的next = head
node.next = head;
//更新新头节点位置
head = node;
size++;
@Override
public void addTail(E value) //O(1)
//申请value节点
Node<E> node = new Node<>(value);
if(head==null )//链表不存在有效节点
head = node;
tail = node;//唯一node 既是头又是尾
else
tail.next = node;
size++;
@Override
public void removeHead()
if(head ==null)
return;
else if(size==1)//head.next = null 只有一个节点
tail=null;
head.value=null;
Node<E> p = head.next;//p只保存地址
head.next=null;
head=p;
size--;
@Override
public void removeTail()
if(head == null)//链表为空
return;
else if(size == 1)//一个节点
head.value=null;
head=null;
tail = null;
else//>=两个节点
//找链表尾巴前趋
Node<E> p =head;
for(;p.next.next==null;p=p.next)
;
p.next = null;
tail.value = null;//防止内存泄漏
tail = p;//更新尾巴指向
size--;
@Override
public void removeValue(E value)
if(head == null)
return;
else if(head.value.compareTo(value) == 0)
removeHead();
else
//找待删节点的前驱
Node<E> p= head;
for(;p.next.value.compareTo(value) != 0;p = p.next)
;
Node<E> q = p.next.next;
p.next.value = null;//防止内存泄漏
//p.next=q.next;
//q.next=null;q.value=null;
p.next.next = null;
p.next = q;
size--;
@Override
public boolean contains(E value)
for(Node<E> p = head;p!=null;p = p.next)
if(p.value.compareTo(value) == 0)
return true;
return false;
@Override
public void change(E srcValue, E aimValue)
for(Node<E> p = head;p!=null;p = p.next)
if (p.value.compareTo(srcValue) == 0)
p.value = aimValue;
@Override
public void show()
for(Node<E> p = head;p!=null;p=p.next)
System.out.print(p.value+" ");
System.out.println();
public Node<E> getHead()
return head;
public void setHead(Node<E> head)
this.head = head;
public void setTail(Node<E> tail)
this.tail = tail;
public Node<E> getTail()
return tail;
public int getSize()
return size;
public void setSize(int size)
this.size = size;
//Node类型
//当前类里边this以外,不用包含外部类对象引用
static class Node<T>
T value;
Node<T> next;
public Node(T value)
this.value = value;
2.单链表练习题
2.1 逆置单链表
/*
一、逆置单链表
*/
public void reverseLink()
if(head == null || size == 1)
return;
Node<E> p=head;
Node<E> q=p.next;
Node<E> s=q.next;
head.next=null;//原来头节点->尾巴节点
while(q != null)
q.next=p;
p = q;
q = s;
if(s!=null)
s = s.next;
tail = head;//新尾巴用原来head更新
head = p;//循环结束 p标志的使新头
2.2 假设两个链表相交,输出相交节点
//二、假设两个链表相交,输出相交节点
public Node<E> getMeetNode(SingleLinkTest<E> link)
//1.让长链表走差值步,长短链表一起向后遍历,
int curSize = size;
int linkSize = link.size;
int diff = curSize-linkSize;
Node<E> longLinkP = diff > 0 ? head : link.head;//longLinkP遍历长链表
Node<E> shortLinkP = diff > 0 ? link.head : head;
//长链表遍历差值步
diff = Math.abs(diff);//取绝对值
while(diff>0)
longLinkP = longLinkP.next;
diff--;
while(longLinkP != shortLinkP)
longLinkP = longLinkP.next;
shortLinkP = shortLinkP.next;
return longLinkP;
2.3 给定一个链表,删除指定节点,O(1)时间复杂度删除指定节点
//三、给定一个链表,删除指定节点,O(1)时间复杂度删除指定节点
public static <E extends Comparable<E>>boolean removeNode(SingleLink<E> link,SingleLink.Node node)
//参数安全检测
if(link == null || node == null)
return false;
if(node == link.getTail())
link.removeTail();
else
node.value = node.next.value;//将当前节点node,下一个节点value赋值给当前节点
node.next = node.next.next;//删除node的下一个节点
link.setSize(link.getSize()-1);//size--
return false;
2.4两个有序单链表合并为一个有序单链表
//四、两个有序单链表合并为一个有序单链表
public void mergeLink(SingleLinkTest<E> link)//this link
if(link == null || head == null && link.head == null)
return;
if(this.head == null)
this.head = link.head;
this.tail = link.tail;
Node<E> p = this.head,q = link.head;
//this.head 更新 两个链表开始的头部value,谁小谁作为起始
this.head = this.head.value.compareTo(link.head.value)<0 ? this.head:link.head;
if(p == head)
p = p.next;
else
q = q.next;
Node<E> s = head;//新链表尾部 连接动作
while(p != null && q != null)
if(p.value.compareTo(q.value) < 0)
s.next = p;
p = p.next;
else
s.next = q;
s = q;//更新到链表尾巴
q = q.next;
if(p == null)
q = q.next;
else
p = p.next;
while(s.next != null)
s = s.next;
this.tail = s;
2.5 判断链表是否有环,并输出相交节点
//五、判断链表是否有环,并输出相交节点
private Node<E> isLoop0()
Node<E> fast = head,slow = head;
do
if(fast == null || fast.next == null)
return null;
fast = fast.next.next;
slow = fast.next;
while(fast != slow);
return fast;
public boolean isLoop()
return !(isLoop0() == null);
//环的入口点
public Node<E> loopNode()
Node<E> fast = isLoop0();//获得相遇点
Node<E> p = head,q = fast;
while(p != q)
p = p.next;
q = q.next;
return p;
今天也要好好学习呀~
以上是关于java-----单链表的主要内容,如果未能解决你的问题,请参考以下文章