您的位置:首页 > 理论基础 > 数据结构算法

java 数据结构

2015-06-30 17:12 459 查看

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

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: