1.排序
public Node sort(){
Node nextnode = null;
Node curnode = head;
int temp = 0;
while(curnode.next!=null){
nextnode = curnode.next;
while(nextnode!=null){
if(curnode.data>nextnode.data){
temp = curnode.data;
curnode.data = nextnode.data;
nextnode.data = temp;
}
nextnode = nextnode.next;
}
curnode = curnode.next;
}
return head;
}
2.反转
反转完全可以套用排序,只需交换数据即可,删除判断
public Node reverse(){
Node nextnode = null;
int temp = 0;
Node curnode = head;
while(curnode.next!=null){
nextnode = curnode.next;
while(nextnode!=null){
temp = curnode.data;
curnode.data = nextnode.data;
nextnode.data = temp;
nextnode = nextnode.next;
}
curnode = curnode.next;
}
return head;
}
3.查找中间节点数值
采用快慢指针方式,快指针一次走两步,慢指针一次走一步,当快指针走完时,慢指针所在位置刚好是链表的中间位置
public Node mid(){
Node quick = this.head;
Node slow = this.head;
while(quick!=null&&quick.next!=null&&quick.next.next!=null){
quick = quick.next.next;
slow = slow.next;
}
System.out.println("mid data:"+slow.data);
return slow;
}
4.查找倒数第K个位置节点的数值
同样是采用两个指针,P1先走K步,然后P1,P2一起走,当P1到达尾部是P2所在位置即倒数第K的位置
public Node FindK(int k){
if(k<1||k>length()){
return null;
}
Node P1 = this.head;
Node P2 = head;
for(int i=0;i<=k-1;i++)
P1 = P1.next;
while(P1!=null){
P1 = P1.next;
P2 = P2.next;
}
System.out.println("data:"+P2.data);
return P2;
}
5.删除重复节点
还是采用两个指针来标记,两个指针在开始时均指向头节点,当第二个节点与头节点数据一致时,P2指向第三个节点再与头节点进行比较,如果数据不一致则P2与P1又同时指向第三个节点了,以此类推一直到结束。
public void deleterepeat(){
Node P1 = head;
while(P1!=null){
Node P2 = P1;
while(P2.next!=null){
if(P1.data==P2.next.data){
P2.next = P2.next.next;
}else{
P2 = P2.next;
}
}
P1 = P1.next;
}
}
6.从未到头输出单链表,递归方式
public void reverseprint(Node rehead){
if(rehead!=null){
reverseprint(rehead.next);
System.out.println(rehead.data);
}
}
传递的参数是Node类的所以在主程序中定义一个
Node rehead = link.head;
System.out.println("reverseprint:");
link.reverseprint(rehead);
7.判断链表是否有环,有环的情况下找出环的入口
如果一个单链表有环,则尾节点相同。借助于两个指针,一个快一个慢,一直向前走,如果某一时刻两个指针重叠了,就说明该链表有环。
public boolean IsLoop(Node node){
Node fast = head;
Node slow = head;
if(fast==null){
return false;
}
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
System.out.println("isloop");
return true;
}
}
return!(fast==null||fast.next==null);
}
找出环的入口
首先在两指针相遇说明有环,并且停下一快一慢的循环,让慢的指针回到起点和快的指针一起向前一步一步走,当两指针再次相遇的地方就是环的入口。
public Node Findloopenter(Node node){
Node fast = head;
Node slow = head;
if(fast==null){
return null;
}
while(fast!=null&&fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
if(fast==null||fast.next==null){
return null;
}
slow = head;
while(slow!=fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
解释一下为什么这样就可以找到入口
head到入口的距离为L,环的周长为R,因为fast是slow的二倍,所以slow没有走完环时就会和fast相遇,相遇时slow在环内走了K,因此
fast = L+n*R+k
slow = L+K
fast从开始直到相遇一直是slow的两倍,所以L+n*R+k = 2*( L+K)
解得L=(n-1)*R+(R-K)
(n-1)*R是整数
此时让slow从头再走L,fast走(R-K),再次相遇即为环入口。