单链表--操作总结
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
证明完毕。
本文主要针对,单链表的创建。
对无环链表的反转,打印。
有环链表的判别,入环点的寻找,打印。
// 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
证明完毕。
相关文章推荐
- C语言-----链表的各项操作总结------双向循环链表
- 链表操作总结
- 链表各种操作总结(个人笔记)
- C语言-----链表的各项操作总结------双向循环链表
- 数据结构之链表单向操作总结
- 单向链表的相关操作总结:创建、删除、查找、排序、统计链表大小、链表的反转和遍历等
- 链表的各种操作函数总结
- 单链表的基本操作(读取、插入、删除)及优缺点总结
- 带头结点的单链表的操作 学习总结
- LeetCode * (21,83,141,160,203,206,234,237)Linked List 简单的链表操作总结
- 部分链表操作总结
- 单链表操作个人归纳(总结)
- 关于链表操作编程实现的一些总结
- 链表操作总结
- C语言---关于链表的各项操作总结-----单向链表
- 数据结构之链表单向操作总结
- 链表的插入操作总结
- 2016年12月23日学习总结----双向循环链表操作程序(头插、尾插、中间插入、删除)
- 单向链表操作总结
- 链表操作类型的问题总结