您的位置:首页 > 其它

单链表--操作总结

2012-07-07 16:42 302 查看
花了一个小时的时间做了一个小小的总结,希望对各位亲,有帮助。废话不多说。开始吧!

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

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

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

// 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

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