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);*/
}
}
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);*/
}
}