Java实现单链表面试题

将节点作为链表的内部类。声明如下:

public class LinkListImpl implements LinkList{
	private Node first;
	private Node last;
	private int length;
	
	class Node{
		private Node next;
		private Object data;
		
		public Node(){}
		
		public Node(Node next, Object data) {
			super();
			this.next = next;
			this.data = data;
		}
	}
	
	@Override
	public int length() {
		return this.length();
	}

	public Node getFirst() {
		return first;
	}
	public Node getLast() {
		return last;
	}
	
	@Override
	public void insertIntoTail(Object data) {
		Node insertNode = new Node(null, data);
		if(first == null){
			first = insertNode;
			last = insertNode;
			return;
		}
		last.next = insertNode;
		this.length++;
	}

	@Override
	public void deleteFromTail() {
		if(length <= 0)
			return;
		else if(length == 1){
			first = null;
			last = null;
		}else{
			Node cur = first;
			Node preCur = null;
			while(cur.next != null){
				preCur = cur;
				cur = cur.next;
			}
			preCur.next = null;
			cur = null;
			last = preCur;
		}
		
		length--;
	}

	@Override
	public void insertIntoFront(Object data) {
		Node insertNode = new Node(first, data);
		first = insertNode;
		if(length == 0)
			last = insertNode;
		length++;
	}

	@Override
	public void deleteFromFront() {
		if(length == 1){
			first = null;
			last = null;
		}else{
			Node tmp = first.next;
			first.next = null;
			first = tmp;
		}
		length--;
		
	}

	@Override
	public void printList() {
		Node cur = first;
		while(cur != null){
			System.out.print(cur.data + " ");
			cur = cur.next;
		}
		System.out.println();
		
	}
}



逆序打印链表:

@Override
	public void reverseShowList(Object cur) {
		if(((Node)cur) != null){
			reverseShowList(((Node)cur).next);
			System.out.print(((Node)cur).data + " ");
		}
	}


运行结果:



约瑟夫环:

@Override
	public void getJosephCircle() {
		if(first == null)
			return;
		Node pCur = first;
		last.next = first;
		
	}

	@Override
	public void setJosephCircle(int m) {
		Node pCur = first;
		Node pPreCur = first;
		getJosephCircle();
		int count;
		while(pCur != pCur.next){
			count = m;
			while(true){
				pPreCur = pCur;
				pCur = pCur.next;
				--count;
				if(count == 1)
					break;
			}
			
			System.out.println("删除节点"+pCur.data);
			pPreCur.next = pCur.next;
			pCur = null;
			pCur = pPreCur.next;
		}
		pCur.next = null;
		
	}



运行结果:

Java实现单链表面试题_第1张图片



逆置单链表:

@Override
	public void reverseList() {
		Node cur = first;
		Node preCur = null;
		Node tail = null;
		
		while(cur != null){
			preCur = cur;
			cur = cur.next;
			preCur.next = tail;
			tail = preCur;
		}
		first = preCur;
		
	}

//逆置单链表
	public void reverseList(){
		
		Node cur = head.next;
		Node preCur = null;
		Node tail = null;
		
		while(cur != null){
			preCur = cur;
			cur = cur.next;
			preCur.next = tail;
			tail = preCur;
		}
		head.next = preCur;
	}

运行结果:



单链表排序(冒泡排序):

@Override
	public void bubbleSort() {
		Node out = first;
		Node in = first;
		Node tail = null;
		while(out != tail){
			in = out;
			while(in.next != tail){
				if((Integer)in.data > (Integer)in.next.data){
					int tmp = (Integer)in.data;
					in.data = in.next.data;
					in.next.data = tmp;
				}
				in = in.next;
			}
			tail = in;
		}
		
	}

运行结果:

获取单链表的中间节点:

@Override
	public Object getMiddleNode() {
		Node pFast = first;
		Node pSlow = first;
		while(pFast != null){
			if(pFast.next == null)
				return pSlow;
			pFast = pFast.next.next;
			pSlow = pSlow.next;
		}
		return pSlow;	
	}

运行结果:



获取倒数第k个节点:

@Override
	public Object getLastLocationAtK(int k) {
		Node pFast = first;
		Node pSlow = first;
		while(k-- > 0){
			pFast = pFast.next;
		}
		while(pFast != null){
			pFast = pFast.next;
			pSlow = pSlow.next;
		}
		return pSlow;
	}

运行结果:




判断单链表是否带环:

	@Override
	public Object hasCircle() {
		if(first == null)
			return null;
		Node pFast = first;
		Node pSlow = first;
		while(true){
			pFast = pFast.next.next;
			pSlow = pSlow.next;
			if(pFast == pSlow){
				break;
			}
			if(pFast == null){
				return null;
			}
		}
		pSlow = first;
		while(true){
			if(pSlow == pFast){
				return pSlow;
			}
			pFast = pFast.next;
			pSlow = pSlow.next;
		}
	}


运行结果:

Java实现单链表面试题_第2张图片

获取任意位置的节点:

@Override
	public Object get(int k) {
		if(k>=length)
			return null;
		Node pCur = first;
		while(k > 0){
			pCur = pCur.next;
			k--;
		}
		return pCur;
	}


获取两个链表的交点(链表不带环):

@Override
	public Object getCrossNode(LinkList l1, LinkList l2) {
		LinkListImpl list1 = (LinkListImpl)l1;
		LinkListImpl list2 = (LinkListImpl)l2;
		Node head1 = list1.getFirst();
		Node head2 = list2.getFirst();
		if(head1 == null || head2 == null)
			return null;
		int len1 = list1.length();
		int len2 = list2.length();
		int step = 0;
		if(len1 > len2){
			step = len1 - len2;
			while(step > 0){
				head1 = head1.next;
				step--;
			}
			while(head1 != null){
				head1 = head1.next;
				head2 = head2.next;
				if(head1 == head2)
					return head1;
			}
		}else{
			
			step = len2 - len1;
			while(step > 0){
				head2 = head2.next;
				step--;
			}
			while(head1 != null){
				head1 = head1.next;
				head2 = head2.next;
				if(head1 == head2)
					return head1;
			}
			
		}
		return null;
	}



获取两个链表的交点(链表可能带环):
@Override
	public Object getCrossNodePlus(LinkList l1, LinkList l2) {
		LinkListImpl list1 = (LinkListImpl)l1;
		LinkListImpl list2 = (LinkListImpl)l2;
		
		if(list1.getFirst() == null)
			return null;
		if(list2.getFirst() == null)
			return null;
		
		//判断两个链表是否带环
		Node crossNode1 = (Node)list1.hasCircle();
		Node crossNode2 = (Node)list2.hasCircle();
		
		//都不带环
		if(crossNode1 == null && crossNode2 == null){
			return getCrossNode(list1, list2);
		}
		
		//都带环
		if(crossNode1 != null && crossNode2 != null){
			Node cur1 = list1.getFirst();
			Node cur2 = list2.getFirst();
			
			if(crossNode1 == crossNode2){
				
				//环外相交,分别求两个链表到环入口点的长度
				int len1 = 0;
				int len2 = 0;
				while(true){
					if(cur1 != crossNode1){
						cur1 = cur1.next;
						len1++;
					}
					if(cur2 != crossNode2){
						len2++;
						cur2 = cur2.next;
					}
					if(cur1 == cur2)
						break;	
				}
				
				cur1 = list1.getFirst();
				cur2 = list2.getFirst();
				int len = len1 - len2;
				if(len>0){
					
					while(len>0){
						cur1 = cur1.next;
						len--;
					}
					
					while(true){
						if(cur1 == cur2)
							return cur1;
						cur1 = cur1.next;
						cur2 = cur2.next;
					}
					
				}else{
					while(len<0){
						cur2 = cur2.next;
						len++;
					}
					
					while(true){
						if(cur1 == cur2)
							return cur1;
						cur1 = cur1.next;
						cur2 = cur2.next;
					}
				}
				
			}else{
				//环内相交,返回任意一个入口点。
				return crossNode1;
			}
		}
			return null;
	}


合并两个有序单链表:

@Override
	public LinkList mergeLists(LinkList l1, LinkList l2) {
		LinkListImpl list1 = (LinkListImpl)l1;
		LinkListImpl list2 = (LinkListImpl)l2;
		if(list1.getFirst() == null)
			return list2;
		if(list2.getFirst() == null)
			return list1;
		Node head1 = list1.getFirst();
		Node head2 = list2.getFirst();
		LinkListImpl list = new LinkListImpl();
		
		Node head = list.getFirst();
		head.next = (Integer)head1.data > (Integer)head2.data ? head2:head1;
		
		//去除头结点操作,如果指向head1,head2的头结点被去除。如果指向head2,head1的头结点被去除
		head1 = head1.next;
		head2 = head2.next;
		
		//具体的插值操作
		while(true){
			if((Integer)head1.data < (Integer)head2.data){
				head.next = head1;
				head1 = head1.next;
			}else{
				head.next = head2;
				head2 = head2.next;
			}
			
			if(head1 == null){
				head.next.next = head2;
				break;
			}
			if(head2 == null){
				head.next.next = head1;
				break;
			}
			head = head.next;
		}
		return list;
	}

运行结果:

Java实现单链表面试题_第3张图片

判断单链表是否带环,求环的入口点,环的长度:

//获取环的入口点
	public Node getCircleEntry(){
		Node pFast = first;
		Node pSlow = first;
		int len = 0;
		while(true){
			pFast = pFast.next.next;
			pSlow = pSlow.next;
			if(pFast == pSlow){
				break;
			}
			if(pFast == null){
				return null;
			}
		}
		pSlow = first;
		while(pSlow != pFast){
			pSlow = pSlow.next;
			pFast = pFast.next;
		}
		
		while(true){
			pFast = pFast.next;
			len++;
			if(pFast == pSlow)
				break;
		}
		System.out.println("环的长度为" + len);
		return pSlow;
	}


C实现: C语言单链表面试题完整代码见git: java单链表面试题




你可能感兴趣的:(JavaSE)