链表经典算法题实现

本文包含链表的以下内容:

  1、单链表的创建和遍历

  2、求单链表中节点的个数

  3、查找单链表中的倒数第k个结点(剑指offer,题15)

  4、查找单链表中的中间结点

  5、合并两个有序的单链表,合并之后的链表依然有序【出现频率高】(剑指offer,题17)

  6、单链表的反转【出现频率最高】(剑指offer,题16)

  7、从尾到头打印单链表(剑指offer,题5)

  8、判断单链表是否有环

  9、取出有环链表中,环的长度

  10、单链表中,取出环的起始点(剑指offer,题56)。本题需利用上面的第8题和第9题。

  11、判断两个单链表相交的第一个交点(剑指offer,题37)

 

package com.he;

import java.util.Stack;

import com.he.LinkList.Node;

public class test32 {
	class Node{
		int data;
		Node next;
		Node(int data){
			this.data = data;
		}
	}
	public Node head =null;
    public Node current = null;
    //添加节点
    public void add(int data){
    	if(head==null){
    		head = new Node(data);
    		current = head;
    	}else{
    		current.next = new Node(data);
    		current = current.next;
    	}
    }
    //方法重载:向链表中添加结点
    public void add(Node node){
    	if(head==null){
    		head = node;
    		current = node;
    	}else{
    		current.next = node;
    		current = current.next;
    	}
    }
    
    //遍历节点
    public void print(Node node){
        current = node;
        while(current!=null){
        	System.out.println(current.data);
        	current = current.next;
        }
    }
    //求单链表节点
    public int getLength(Node node){
    	current = node;
    	int length = 0;
    	if(current == null){
    		return 0;
    	}
    	while(current!=null){
    		length++;
    		current = current.next;   		
    	}
		return length;  
    	
    }
    //查找单链表中的倒数第k个结点
    public Node findLastNode(Node node,int k){
    	if(node==null || k==0){
    		return null;
    	}
    	Node first = node;
    	Node second = node;
    	for (int i = 0; i < k-1; i++) {
			second = second.next;
			if(second == null){
				return null;
			}
		}
    	while(second.next!=null){
    		first = first.next;
    		second = second.next;
    	}
    	return first;
    }
    
    //查找单链表中的中间结点
    public Node findMiddle(Node node){
    	if(node==null){
    		return null;
    	}
    	Node first = node;
    	Node second = node;
    	while(first!=null && second!=null){
    		if(second.next!=null){
    			second = second.next.next;
    		}else{
    			return first;
    		}   
    		first = first.next;
    	}
    	return first;
    }
   
    //合并两个有序的单链表,合并之后的链表依然有序
    public Node getMergeLinkList(Node head1,Node head2){
    	if(head1==null && head2==null){
    		return null;
    	}
    	if(head1==null){
    		return head2;
    	}
    	if(head2==null){
    		return head1;
    	}
    	Node head;
    	Node current;
    	if(head1.data < head2.data){
    		head = head1;
    		current = head1;
    		head1 = head1.next;
    	}else{
    		head = head2;
    		current = head2;
    		head2 = head2.next;
    	}
    	while(head1!= null && head2!= null){
    		if(head1.data < head2.data){
    			current.next = head1;
    			current = current.next;
    			head1 = head1.next;
    		}else{
    			current.next = head2;
    			current = current.next;
    			head2 = head2.next;
    		}
    	}
    	if(head1 == null){
    		current.next = head2;
    	}
    	if(head2 == null){
    		current.next = head1;
    	}
    	return head;
    }
    //单链表的反转
    public Node reverseList(Node head){
    	if(head==null && head.next==null){
    		return head;
    	}
    	Node reverseHead = null;
    	Node next = null;
    	Node current = head;
    	while(current!=null){
    		next = current.next;
    		current.next = reverseHead;
    		reverseHead = current;
    		current = next;
    	}
    	return reverseHead;
    }
     
  //翻转链表方法2
   public ListNode reverseList(ListNode head) {
        ListNode prev = null;
        while(head!=null){
            ListNode tmp = head.next;
            head.next = prev;
            prev = head;
            head = tmp;
        }
        return prev;
    }
    
    //从尾到头打印单链表
    public void reversePrint(Node head){
    	if(head == null){
    		return;
    	}
    	Stack<Node> stack = new Stack<Node>();
    	Node current = head;
    	while(current!=null){
    		stack.push(current);
    		current = current.next;
    	}
    	while(stack.size()>0){
    		System.out.println(stack.pop().data);
    	}
    }
    
    //判断单链表是否有环
    public boolean hasCycle(Node head){
    	if(head == null){
    		return false;
    	}
    	Node first = head;
    	Node second = head;
    	while(second!=null){
    		first = first.next;
    		if(second.next!=null){
    			second = second.next.next;
    		}else{
    			return false;
    		}    		
    		if(first == second){
    			return true;
    		}
    	}
    	return false;
    }
   
    //取出有环链表中,环的长度
    public int getCycleLength(Node node){
    	int length = 0;
    	Node current = node;
    	while(current!=null){
    		current = current.next;
    		length++;
    		if(current == node){
    			return length;
    		}
    	}
    	return length;
    }
    
    //单链表中,取出环的起始点
    public Node getCycleStart(Node head,int cycleLength){
    	if(head==null){
    		return null;
    	}
    	Node first = head;
    	Node second = head;
    	for (int i = 0; i < cycleLength; i++) {
			second = second.next;
		}
    	while(first!=null&& second!=null){
    		if(first == second){
    			return first;
    		}
    		first = first.next;
    		second = second.next;
    	}
    	return null;
    }
    
    //求两个单链表相交的第一个交点
    public Node getFirstCommonNode(Node head1,Node head2){
    	if(head1==null|| head2==null){
    		return null;
    	}
    	int length1 = getLength(head1);
    	int length2 = getLength(head2);
    	int lengthDif = 0;
    	Node longHead = null;
    	if(length1 > length2){
    		lengthDif = length1-length2;
    		longHead = head1;
    	}else{
    		lengthDif = length2-length1;
    		longHead = head2;
    	}
    	for (int i = 0; i < lengthDif; i++) {
		    longHead = longHead.next;	
		}
    	while(longHead!=null && head2!=null){
    		longHead = longHead.next;
    		head2 = head2.next;
    		if(longHead == head2){
    			return head2;
    		}
    	}
		return null;    	
    }
    
    public static void main(String[] args) {
	    test32 sh = new test32();
	    for (int i = 0; i < 4; i++) {
			sh.add(i);
		}
	   // sh.print(sh.head);
	   // System.out.println(sh.getLength(sh.head));
	   // System.out.println(sh.findLastNode(sh.head, 3).data);
	   //sh.print(sh.reverseList(sh.head));
	    sh.add(sh.head);
	    System.out.println(sh.hasCycle(sh.head));
	    System.out.println(sh.hasCycle(sh.head));
	    System.out.println(sh.getCycleLength(sh.head));
	    System.out.println(sh.getCycleStart(sh.head, sh.getCycleLength(sh.head)).data);	      
//	    test32 sh1 = new test32();
//	    for (int i = 6; i < 8; i++) {
//			sh1.add(i);
//		} 
//	    sh.print(sh.getMergeLinkList(sh.head, sh1.head));
	    
	}
}

 

 

 

 

 

    原文作者:will的猜想
    原文地址: https://blog.csdn.net/u012129558/article/details/52575543
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞