将节点作为链表的内部类。声明如下:
public class LinkListImpl implements LinkList{
private Node first;
private Node last;
private int length;
class Node{
private Node next;
private Object data;
public Node(){}
public Node(Node next, Object data) {
super();
this.next = next;
this.data = data;
}
}
@Override
public int length() {
return this.length();
}
public Node getFirst() {
return first;
}
public Node getLast() {
return last;
}
@Override
public void insertIntoTail(Object data) {
Node insertNode = new Node(null, data);
if(first == null){
first = insertNode;
last = insertNode;
return;
}
last.next = insertNode;
this.length++;
}
@Override
public void deleteFromTail() {
if(length <= 0)
return;
else if(length == 1){
first = null;
last = null;
}else{
Node cur = first;
Node preCur = null;
while(cur.next != null){
preCur = cur;
cur = cur.next;
}
preCur.next = null;
cur = null;
last = preCur;
}
length--;
}
@Override
public void insertIntoFront(Object data) {
Node insertNode = new Node(first, data);
first = insertNode;
if(length == 0)
last = insertNode;
length++;
}
@Override
public void deleteFromFront() {
if(length == 1){
first = null;
last = null;
}else{
Node tmp = first.next;
first.next = null;
first = tmp;
}
length--;
}
@Override
public void printList() {
Node cur = first;
while(cur != null){
System.out.print(cur.data + " ");
cur = cur.next;
}
System.out.println();
}
}
逆序打印链表:
@Override
public void reverseShowList(Object cur) {
if(((Node)cur) != null){
reverseShowList(((Node)cur).next);
System.out.print(((Node)cur).data + " ");
}
}
运行结果:
约瑟夫环:
@Override
public void getJosephCircle() {
if(first == null)
return;
Node pCur = first;
last.next = first;
}
@Override
public void setJosephCircle(int m) {
Node pCur = first;
Node pPreCur = first;
getJosephCircle();
int count;
while(pCur != pCur.next){
count = m;
while(true){
pPreCur = pCur;
pCur = pCur.next;
--count;
if(count == 1)
break;
}
System.out.println("删除节点"+pCur.data);
pPreCur.next = pCur.next;
pCur = null;
pCur = pPreCur.next;
}
pCur.next = null;
}
逆置单链表:
@Override
public void reverseList() {
Node cur = first;
Node preCur = null;
Node tail = null;
while(cur != null){
preCur = cur;
cur = cur.next;
preCur.next = tail;
tail = preCur;
}
first = preCur;
}
//逆置单链表
public void reverseList(){
Node cur = head.next;
Node preCur = null;
Node tail = null;
while(cur != null){
preCur = cur;
cur = cur.next;
preCur.next = tail;
tail = preCur;
}
head.next = preCur;
}
运行结果:
@Override
public void bubbleSort() {
Node out = first;
Node in = first;
Node tail = null;
while(out != tail){
in = out;
while(in.next != tail){
if((Integer)in.data > (Integer)in.next.data){
int tmp = (Integer)in.data;
in.data = in.next.data;
in.next.data = tmp;
}
in = in.next;
}
tail = in;
}
}
运行结果:
获取单链表的中间节点:
@Override
public Object getMiddleNode() {
Node pFast = first;
Node pSlow = first;
while(pFast != null){
if(pFast.next == null)
return pSlow;
pFast = pFast.next.next;
pSlow = pSlow.next;
}
return pSlow;
}
获取倒数第k个节点:
@Override
public Object getLastLocationAtK(int k) {
Node pFast = first;
Node pSlow = first;
while(k-- > 0){
pFast = pFast.next;
}
while(pFast != null){
pFast = pFast.next;
pSlow = pSlow.next;
}
return pSlow;
}
运行结果:
@Override
public Object hasCircle() {
if(first == null)
return null;
Node pFast = first;
Node pSlow = first;
while(true){
pFast = pFast.next.next;
pSlow = pSlow.next;
if(pFast == pSlow){
break;
}
if(pFast == null){
return null;
}
}
pSlow = first;
while(true){
if(pSlow == pFast){
return pSlow;
}
pFast = pFast.next;
pSlow = pSlow.next;
}
}
获取任意位置的节点:
@Override
public Object get(int k) {
if(k>=length)
return null;
Node pCur = first;
while(k > 0){
pCur = pCur.next;
k--;
}
return pCur;
}
@Override
public Object getCrossNode(LinkList l1, LinkList l2) {
LinkListImpl list1 = (LinkListImpl)l1;
LinkListImpl list2 = (LinkListImpl)l2;
Node head1 = list1.getFirst();
Node head2 = list2.getFirst();
if(head1 == null || head2 == null)
return null;
int len1 = list1.length();
int len2 = list2.length();
int step = 0;
if(len1 > len2){
step = len1 - len2;
while(step > 0){
head1 = head1.next;
step--;
}
while(head1 != null){
head1 = head1.next;
head2 = head2.next;
if(head1 == head2)
return head1;
}
}else{
step = len2 - len1;
while(step > 0){
head2 = head2.next;
step--;
}
while(head1 != null){
head1 = head1.next;
head2 = head2.next;
if(head1 == head2)
return head1;
}
}
return null;
}
@Override
public Object getCrossNodePlus(LinkList l1, LinkList l2) {
LinkListImpl list1 = (LinkListImpl)l1;
LinkListImpl list2 = (LinkListImpl)l2;
if(list1.getFirst() == null)
return null;
if(list2.getFirst() == null)
return null;
//判断两个链表是否带环
Node crossNode1 = (Node)list1.hasCircle();
Node crossNode2 = (Node)list2.hasCircle();
//都不带环
if(crossNode1 == null && crossNode2 == null){
return getCrossNode(list1, list2);
}
//都带环
if(crossNode1 != null && crossNode2 != null){
Node cur1 = list1.getFirst();
Node cur2 = list2.getFirst();
if(crossNode1 == crossNode2){
//环外相交,分别求两个链表到环入口点的长度
int len1 = 0;
int len2 = 0;
while(true){
if(cur1 != crossNode1){
cur1 = cur1.next;
len1++;
}
if(cur2 != crossNode2){
len2++;
cur2 = cur2.next;
}
if(cur1 == cur2)
break;
}
cur1 = list1.getFirst();
cur2 = list2.getFirst();
int len = len1 - len2;
if(len>0){
while(len>0){
cur1 = cur1.next;
len--;
}
while(true){
if(cur1 == cur2)
return cur1;
cur1 = cur1.next;
cur2 = cur2.next;
}
}else{
while(len<0){
cur2 = cur2.next;
len++;
}
while(true){
if(cur1 == cur2)
return cur1;
cur1 = cur1.next;
cur2 = cur2.next;
}
}
}else{
//环内相交,返回任意一个入口点。
return crossNode1;
}
}
return null;
}
@Override
public LinkList mergeLists(LinkList l1, LinkList l2) {
LinkListImpl list1 = (LinkListImpl)l1;
LinkListImpl list2 = (LinkListImpl)l2;
if(list1.getFirst() == null)
return list2;
if(list2.getFirst() == null)
return list1;
Node head1 = list1.getFirst();
Node head2 = list2.getFirst();
LinkListImpl list = new LinkListImpl();
Node head = list.getFirst();
head.next = (Integer)head1.data > (Integer)head2.data ? head2:head1;
//去除头结点操作,如果指向head1,head2的头结点被去除。如果指向head2,head1的头结点被去除
head1 = head1.next;
head2 = head2.next;
//具体的插值操作
while(true){
if((Integer)head1.data < (Integer)head2.data){
head.next = head1;
head1 = head1.next;
}else{
head.next = head2;
head2 = head2.next;
}
if(head1 == null){
head.next.next = head2;
break;
}
if(head2 == null){
head.next.next = head1;
break;
}
head = head.next;
}
return list;
}
运行结果: 判断单链表是否带环,求环的入口点,环的长度:
//获取环的入口点
public Node getCircleEntry(){
Node pFast = first;
Node pSlow = first;
int len = 0;
while(true){
pFast = pFast.next.next;
pSlow = pSlow.next;
if(pFast == pSlow){
break;
}
if(pFast == null){
return null;
}
}
pSlow = first;
while(pSlow != pFast){
pSlow = pSlow.next;
pFast = pFast.next;
}
while(true){
pFast = pFast.next;
len++;
if(pFast == pSlow)
break;
}
System.out.println("环的长度为" + len);
return pSlow;
}