java 数据结构

 package hello; 





public class LinkListOperate {


private class Node{

private String data;
private Node next;

public Node(){

}
public Node(String data,Node next){

this.data=data;
this.next=next;
}
}

private Node header;
private Node tail;
private int size;

public LinkListOperate(){

header=null;
tail=null;

}

public LinkListOperate(String element){

header=new Node(element,null);
tail=header;
size++;
}


public void setCycle(){

tail.next=header.next;
}

public void add(String element){

if(header==null){

header=new Node(element,null);
tail=header;
}else{

Node newNode=new Node(element,null);

tail.next=newNode;

tail=newNode;
}
size++;
}


public void reverse(){  //反向输出一个链表, 正常情况,一个链表的前一个节点的next指向后一个节点,反向即后一个节点的next指向前一个节点。

Node prev=header;
Node qcurrent=header.next;
Node pnext=null;
while(qcurrent!=null){

pnext=qcurrent.next;   //保存当前变量
qcurrent.next=prev;   //将当前节点的next指向前一个节点
prev=qcurrent;    //当前节点变为前一个节点
qcurrent=pnext;   //下一个节点即为当前节点
}

header.next=null;
header=prev;
}



public void reverseRecursion(Node n1){   //使用递归函数,反向输出

//Node n1=header;

if(n1==null){
return;
}
else{
reverseRecursion(n1.next);   // 递归调用
System.out.print(n1.data);
}
}




public String middleList(){  //输出链表中间位置,两个指针,一个走一步,一个每次走两步,后面的到达终点后,第一个指针所在的位置就是中间

Node n1=header;
Node n2=header.next;

while(n2 != null){

n1=n1.next;   //一次一步
n2=n2.next.next;  //一次两步
}

return n1.data;

}


public boolean isCycle(){   //判断链表是否存在环路,两个指针,一个每次一步,一个每次两步,如果两个相遇(即相等),则存在环路

Node n1=header;
Node n2=header.next;
while(n2!=null){

n1=n1.next;
n2=n2.next.next;
if(n2==n1){

return true;
}
}
return false;
}


public String findRKNode(int k){   //查找倒数第K个节点



Node n1=header;
Node n2=header;
for(int i=0;i<=k;i++){

n1=n1.next;
}

while(n1!=null){

n1=n1.next;
n2=n2.next;
}


return n2.data;
}


public boolean isCrossing(Node a,Node b){   //判断两个链表是否相交,  如果相交,最后一个节点肯定是共有的。

if(a==null||b==null){

return false;
}

Node n1=a;
while(n1.next!=null){   //循环到最后一个节点

n1=n1.next;
}

Node n2=b;
while(n2.next!=null){  //循环到最后一个节点
n2=n2.next;
}

return n1==n2;     //判断最后一个节点是否相等


}



public Node theFirstCrossNode(Node a,Node b){   //判断两个链表相交的第一个节点

if(a==null|b==null){

return null;
}

Node n1=a;
int len1=1;
while(n1.next!=null){

n1=n1.next;
len1++;
}

Node n2=b;
int len2=1;
while(n2.next!=null){

n2=n2.next;
len2++;
}

if(n1!=n2){                   //先判断有没有相交,如果没有,返回null

return null;
}

Node n11=a;
Node n22=b;
if(len1>len2){            //如果有相交,如果第一个链表长度长,则先走到len1-len2,然后两个一块走,如果相等则是第一个交点

int k=len1-len2;
while(k>0){

n11=n11.next;
k--;
}
}else{

int k=len2-len1;
while(k>0){

n22=n22.next;
k--;
}
}

while(n11!=n22){

n11=n11.next;
n22=n22.next;
}

return n22;

}




public Node theFirstCycleNode(Node a){          //单链表环路,进入环路的第一个节点

if(a==null||a.next==null){

return null;
}

Node nFast=a;
Node nSlow=a;
while(nFast!=null && nFast.next!=null){      //先判断是否存在环路,一旦存在环路,则中断,此时的节点在环中的某个节点

nSlow=nSlow.next;
nFast=nFast.next.next;
if(nSlow==nFast){

break;
}
}

if(nFast==null || nFast.next==null){

return null;
}

Node assumTail=nSlow;              //假设环中的节点作为尾节点, 这样就变为两个链表的相交问题,同上一函数
Node header1=header;   
Node header2=assumTail.next;   //设置两个链表的header

int len1=1;
Node n1=header1;
while(n1!=assumTail){   //终点为环中的尾节点

n1=n1.next;
len1++;
}

int len2=1;
Node n2=header2;
while(n2!=assumTail){

n2=n2.next;
len2++;
}

Node n11=header1;
Node n22=header2;

if(len1>len2){

int k=len1-len2;
while(k>0){

n11=n11.next;
k--;
}
}else{

int k=len2-len1;
while(k<0){

n22=n22.next;
k--;
}
}

while(n11!=n22){

n11=n11.next;
n22=n22.next;
}

return n11;
}

public String toString(){



StringBuilder sb=new StringBuilder("[");

for(Node current=header;current!=null;current=current.next){

sb.append(current.data.toString()+",");
}

int length=sb.length();


return sb.delete(length-1, length).append("]").toString();


}





public static void main(String[] args) {
// TODO Auto-generated method stub


LinkListOperate llo=new LinkListOperate();
llo.add("a");
llo.add("b");
llo.add("c");
llo.add("d");
llo.add("e");
//llo.setCycle();

LinkListOperate llo1=new LinkListOperate();
llo1.add("a");

llo1.add("d");
llo1.add("e");

//llo1.header.next=llo.header.next.next;   //设置两个链表相交

//System.out.println("is crossing?"+llo1.isCrossing(llo.header, llo1.header));
//System.out.println("The first crossing node:"+llo1.theFirstCrossNode(llo.header,llo1.header).data);


//System.out.println("is cycle?"+llo.isCycle());
//System.out.println("This first cycle node:"+llo.theFirstCycleNode(llo.header).data);
/*llo.reverse();

llo.reverseRecursion(llo.header);
System.out.println();

System.out.println(llo.middleList());
System.out.println(llo.findRKNode(2));
System.out.println(llo);*/

}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值