单链表--操作总结

来源:互联网 发布:网络相声大会 编辑:程序博客网 时间:2024/05/23 15:52

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

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

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

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

// 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;}elsecout<<"无环"<<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
证明完毕。