寻找倒数第k个结点
public void lastk(int k){
Entry cur1=head;
Entry cur2=head;
if(k<0||k>getlength()){
System.out.println("超出链表范围");
}
while(k-1>0){//当k合法的时候,让cur1先往后移动,比如要寻找倒数第二个结点,则让cur1先往后移动俩次
cur1=cur1.next;
k--;
}
while(cur1.next!=null){//cur1先移动之后,让cur1与cur2同时移动
cur1=cur1.next;
cur2=cur2.next;
if(cur1.next==null){//当cur1移动到最后一个结点时,cur2此时就是我们需要找出的结点
System.out.println(cur2.data);
}
}
}
代码原理:
让cur1先往后移动,比如要寻找倒数第二个结点,则让cur1先往后移动俩次,然后cur1 cur2同时向后移动,直到cur1移动到最后一个结点,此时,cur2就移动到了我们需要找的结点。
判断一个链表是否有环:
public boolean isloop(){//判断是否有环
Entry fast=head;
Entry slow=head;
while(fast!=null&&fast.next!=null)
{
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
return true;
}
}
return false;
}
设置两个指针(fast, slow),初始值都指向头结点,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。
计算环的长度:
public void getLoopLength(){
Entry fast = head;
Entry slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
//输出环长
while(fast == slow) {
int len = 0;
fast = fast.next.next;
slow = slow.next;
while (fast != slow) {
len++;
fast = fast.next.next;
slow = slow.next;
}System.out.println("环长度为:"+len);
}
}
}
从第一次相遇点也就是环的起始位置开始,快慢指针同时继续移动,直到下次二者相遇,慢指针走过的长度就是环的长度
寻找环的起点
public void begin()
{
Entry fast=head;
Entry slow=head;
while(fast!=null&&fast.next!=null)
{
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
break;}
}
Entry a=head;
while (a != slow) {
a = a.next;//让a从头结点开始,slow从相遇点开始,当俩者再次相遇的结点就是环的起始结点
slow = slow.next;
}
System.out.println(slow.data);
}
如图所示
从表头到入口点的距离,等于从相遇点到入口点的距离。
判断俩个单链表是否相交
public static void cteatcut(TestLink t1,TestLink t2){//先创建俩个有交点的单链表
TestLink.Entry head1=t1.getHead();
TestLink.Entry head2=t2.getHead();
head1.next.next=head2.next.next;
}
public static boolean iscut(TestLink t1,TestLink t2){
TestLink.Entry head1=t1.getHead();
TestLink.Entry head2=t2.getHead();
int len1=t1.getlength();
int len2=t2.getlength();
int my_len=len1-len2;
if(my_len<0){//为了保证len1代表的是比较长的单链表
len1=t2.getlength();
len2=t1.getlength();
}
for(int i=0;i<my_len;i++){//让长的单链表先向后移动my—len个结点,此时,俩个链表才相当于在同个起跑线上
head1=head1.next;
}
while(head1!=null&&head2!=null&&head1!=head2){//遍历俩个单链表,如果有一样的结点,则说明俩个单链表有交点
head1=head1.next;
head2=head2.next;
}
if(head1==head2&&head1!=null){
return true;
}else{
return false;
}
}
单链表的逆置
public void nizhi1(){//逆顺打印
Entry newhead=null;
Entry prev=null;
Entry cur=head;
while(cur!=null){
Entry curnest=cur.next;
if(curnest==null){
newhead=cur;
}
cur.next=prev;
prev=cur;
cur=curnest;
}
}