单链表--操作总结

花了一个小时的时间做了一个小小的总结,希望对各位亲,有帮助。废话不多说。开始吧!

本文主要针对,单链表的创建。

对无环链表的反转,打印。

有环链表的判别,入环点的寻找,打印。

// TestListHuan.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <string>
#define N 20 //链表的长度
using namespace std;

struct ListNode
{
	int data;
	ListNode *next;
};

//打印链表
void print(ListNode *p,ListNode *flagH)
{
	ListNode *q=p;
	int count=0;
	while(q)
	{
		cout<<" "<<q->data;
		q=q->next;
		if(q==flagH)
		{
			count++;
			if(count>1)
			{
				cout<<" "<<flagH->data<<endl;
				break;
			}
		}
	}
	cout<<endl;
}

//创建无环链表
ListNode *creatList()
{
	ListNode *pHead,*pRear,*p;
	int x;
	string listName;
	pHead=(ListNode *)malloc(sizeof(ListNode));
	pRear=pHead;
	p=pHead;
	cout<<"Please input the listName:"<<endl;
	cin>>listName;
	
	for(int i=0;i<N;i++)
	{
		x=rand()%100;
		pHead=(ListNode*)malloc(sizeof(ListNode));
		pHead->data=x;
		pRear->next=pHead;
		pRear=pHead;
	}
	pRear->next=NULL;
	print(p->next,NULL);
	return p->next;
}

ListNode *creatListHuan()//创建有环链表
{
	ListNode *pHead,*pRear,*p,*t;
	int x;
	string listName;
	pHead=(ListNode *)malloc(sizeof(ListNode));
	pRear=pHead;
	p=pHead;
	cout<<"Please input the listName:"<<endl;
	cin>>listName;
	
	for(int i=0;i<N;i++)
	{
		x=rand()%100;
		pHead=(ListNode*)malloc(sizeof(ListNode));
		pHead->data=x;
		pRear->next=pHead;
		pRear=pHead;
		if(i==4)
		{
			t=pRear;
		}
	}
	pRear->next=t;
	return p->next;
}

//反转无环链表
ListNode *revrseList(ListNode *p)
{
	if(p==NULL||p->next==NULL)
		return p;
	ListNode *pHead=NULL;
	ListNode *q=p;
	ListNode *t=NULL;
	t=NULL;
	while(q)
	{
		pHead=q->next;
		q->next=t;
		t=q;
		q=pHead;
	}
	return t;
}

///下面谈下有环的情况
//验证该链表是否有环
ListNode *getHuan(ListNode *p)
{
	if(p==NULL||p->next==NULL)
		return NULL;
	ListNode *q=p;
	ListNode *t=p;
	while(q!=NULL)
	{
		t=t->next->next;
		if(t==NULL)
			break;
		q=q->next;
		
		if(q==t)
			break;
	}
	if(t)
		return t;
	return NULL;
}

//*p 链表头结点,*q是相遇结点  这个是重点哦!有不懂的留言哦!
ListNode *getDot(ListNode *p,ListNode *q)
{
	if(p==NULL||p->next==NULL)
		return NULL;
	while(p!=NULL)
	{
		p=p->next;
		q=q->next;
		if(p==q)
			break;
	}
	if(p)
		return p;
	return NULL;
}
int main()
{
	printf("Hello World!\n");
	ListNode *p,*q,*pH,*qH;
	p=creatList();
	q=revrseList(p);
	print(q,NULL);

	//*****下面谈下有环的事情
	pH=creatListHuan();
	qH=pH;
	ListNode *flag=getHuan(pH);
	if(flag)
	{
		cout<<"有环"<<endl;
		ListNode *hP=getDot(pH,flag);
		print(qH,hP);
		cout<<"入环点的值:"<<hP->data<<endl;
	}
	else
		cout<<"无环"<<endl;
	
	return 0;
}

两个小问题:

1.在有环的情况下,为什么慢指针在没有走完一整圈,就会和快指针相遇?
2.从相遇结点,和头结点同时一步一步走,相遇点为什么就是入环点?

现在时间:2012年8月2日10:12:03
真的对不起大家,这么久才来回答这两个小问题。
首先我们来看第一个问题:
为什么慢指针没有走完一圈就会相遇。
我们可也是用反证法。
假设慢指针走完了一圈,他们才相遇的话,你可以再往前退,会发现,在此之前必会相遇。你可以做一个简单的试验,画一个圈,圈上N个点,一开始两个人,站在不同的点上,朝着同一方向,不同速度的移动。在那个慢的人没有走完一圈的时候,他们就会相遇。
关于第二个问题:根据数学推理。得到
在两个指针相遇的点,该点距离环入口点的距离,正好等于链表的头节点到环入口点的距离!证明如下:
假设:头结点到环入口点的距离为x,整个链表长度为L,相遇的时候距离环入口点的距离为z,慢指针走的是快的一半。假设慢的走了s,r为环的长度,则 s+nr=2s 即:s=nr
s=x+z;
x=s-z=nr-z=(n-1)r+r-z=(n-1)r+L-a-z
证明完毕。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值