补充4:单链表的应用

1.排序

	public Node sort(){
		Node nextnode = null;
		Node curnode = head;
		int temp = 0;

		while(curnode.next!=null){
			nextnode = curnode.next;
		while(nextnode!=null){
			if(curnode.data>nextnode.data){
				temp = curnode.data;
				curnode.data = nextnode.data;
				nextnode.data = temp;
			}
			nextnode = nextnode.next;
		}
		curnode = curnode.next;
		}
		return head;
	}

2.反转

反转完全可以套用排序,只需交换数据即可,删除判断

	public Node reverse(){
		Node nextnode = null;
		int temp = 0;
		Node curnode = head;
		
		while(curnode.next!=null){
			nextnode = curnode.next;
		while(nextnode!=null){			
				temp = curnode.data;
				curnode.data = nextnode.data;
				nextnode.data = temp;			
			nextnode = nextnode.next;
		}
		curnode = curnode.next;
		}
		return head;
	}

3.查找中间节点数值

采用快慢指针方式,快指针一次走两步,慢指针一次走一步,当快指针走完时,慢指针所在位置刚好是链表的中间位置

	public Node mid(){
		Node quick = this.head;
		Node slow = this.head;
		while(quick!=null&&quick.next!=null&&quick.next.next!=null){
			quick = quick.next.next;
			slow = slow.next;
		}
		System.out.println("mid data:"+slow.data);
		return slow;
	}

4.查找倒数第K个位置节点的数值

同样是采用两个指针,P1先走K步,然后P1,P2一起走,当P1到达尾部是P2所在位置即倒数第K的位置

	public Node FindK(int k){
		if(k<1||k>length()){
			return null;
		}
		Node P1 = this.head;
		Node P2 = head;
		for(int i=0;i<=k-1;i++)
			P1 = P1.next;
			while(P1!=null){
				P1 = P1.next;
				P2 = P2.next;
			}		
			System.out.println("data:"+P2.data);
			return P2;
	}

5.删除重复节点

    还是采用两个指针来标记,两个指针在开始时均指向头节点,当第二个节点与头节点数据一致时,P2指向第三个节点再与头节点进行比较,如果数据不一致则P2与P1又同时指向第三个节点了,以此类推一直到结束。

	public void deleterepeat(){
		Node P1 = head;
		while(P1!=null){
			Node P2 = P1;
			while(P2.next!=null){
				if(P1.data==P2.next.data){
					P2.next = P2.next.next;
				}else{
					P2 = P2.next;
				}
			}
			P1 = P1.next;
		}
	}

6.从未到头输出单链表,递归方式

	public void reverseprint(Node rehead){
		if(rehead!=null){
			reverseprint(rehead.next);
			System.out.println(rehead.data);
		}
	}

传递的参数是Node类的所以在主程序中定义一个

                Node rehead = link.head;
		System.out.println("reverseprint:");
		link.reverseprint(rehead);

7.判断链表是否有环,有环的情况下找出环的入口

    如果一个单链表有环,则尾节点相同。借助于两个指针,一个快一个慢,一直向前走,如果某一时刻两个指针重叠了,就说明该链表有环。

	public boolean IsLoop(Node node){
		Node fast = head;
		Node slow = head;
		if(fast==null){
			return false;
		}
		while(fast!=null&&fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				System.out.println("isloop");
				return true;
			}
		}
		return!(fast==null||fast.next==null);
	}

    找出环的入口

首先在两指针相遇说明有环,并且停下一快一慢的循环,让慢的指针回到起点和快的指针一起向前一步一步走,当两指针再次相遇的地方就是环的入口。

	public Node Findloopenter(Node node){
		Node fast = head;
		Node slow = head;
		if(fast==null){
			return null;
		}
		while(fast!=null&&fast.next!=null){
			fast = fast.next.next;
			slow = slow.next;
			if(fast == slow){
				break;
			}
		}
		if(fast==null||fast.next==null){
			return null;
		}
		
		slow = head;
		while(slow!=fast){
			slow = slow.next;
			fast = fast.next;
		}
		return slow;
	}

解释一下为什么这样就可以找到入口


head到入口的距离为L,环的周长为R,因为fast是slow的二倍,所以slow没有走完环时就会和fast相遇,相遇时slow在环内走了K,因此

fast = L+n*R+k

slow = L+K

fast从开始直到相遇一直是slow的两倍,所以L+n*R+k = 2*( L+K)

解得L=(n-1)*R+(R-K)

(n-1)*R是整数

此时让slow从头再走L,fast走(R-K),再次相遇即为环入口。

猜你喜欢

转载自blog.csdn.net/cherishgf/article/details/80802859
今日推荐