单链表的可以有许多问题,这是我特意整理一下的有关他的相关操作,给出代码,有需要的可以自己调试,重要的就是关于环的一些操作:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef int Elemtype;
typedef struct Node{
Elemtype data;
struct Node *next;
}Node,*Linklist;
void lengthList(Linklist &L){//求基础长度
Linklist p,q;
p=L->next;
while(p!=NULL){
L->data++;
p=p->next;
}
}
void createList(Linklist &L){//创造单链表
L=new Node;
Linklist p,q;
int x;
L->data=0;
q=L;
cin>>x;
while(x!=-999){
p=new Node;
p->data=x;
q->next=p;
q=p;
cout<<" if you want to continue to input some data,please don‘t input -999"<<endl;
cin>>x;
}
p->next=NULL;
lengthList(L);
}
void display(Linklist &L){//输出
Linklist p;
p=L->next;
while(p!=NULL){
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
void ReverseList(Linklist &L){//单链表反转/逆序
Linklist p,q;
display(L);
p=L->next->next;
L->next->next=NULL;
while(p!=NULL){
q=p;
p=p->next;
q->next=L->next;
L->next=q;
}
display(L);
}
void NIndex(Linklist &L){//求单链表倒数第N个数
int N;
cin>>N;//请输入倒数第几个
int d=L->data-N+1;
int i=1;
Linklist p=L->next;
while(i<d){
i++;
p=p->next;
}
cout<<p->data<<endl;
}
void middle(Linklist &L){//找到单链表的中间结点
// int d=L->data/2+1,i=1; //通过使用链表总长实现
// Linklist p;
// p=L->next;
// while(i<d){
// i++;
// p=p->next;
// }
// cout<<p->data<<endl;
Linklist p,q; //通过双指针实现
p=L->next;
q=L->next;
while(q->next!=NULL&&q->next->next!=NULL){
p=p->next;
q=q->next->next;
// if(q->next==NULL){
// break;
// }
}
cout<<p->data;
}
bool judgement(Linklist L){ //如何判断链表是否有环的存在
Linklist slow,fast;
slow=L->next;
fast=L->next->next;
while(slow!=fast){
slow=slow->next;
fast=fast->next->next;
if(fast->next==NULL||fast->next->next==NULL){
cout<<"没有环";
return false;
}
}
cout<<"有一个环";
return true;
}
void circle(Linklist &L,int a){//单链表建环,无环链表变有环
Linklist p,q;
p=L->next;
int i;
for( i=1;p->next!=NULL;i++){
if(i==a)
q=p;
p=p->next;
}
p->next=q;
}
void BulidListLoop(Linklist &L, int num){//单链表建环,无环链表变有环的另一种操作
int i = 0;
Linklist cur = L;
Linklist tail = NULL;
if(num <= 0 || L == NULL)
{
return ;
}
for(i = 1; i < num; ++i)
{
if(cur == NULL)
{
return ;
}
cur = cur->next;
}
tail = cur;
while(tail->next)
{
tail = tail->next;
}
tail->next = cur;
return ;
}
void lengthcircle(Linklist L){//如何知道环的长度?
Linklist slow,fast;
int i;
slow=L->next;
fast=L->next->next;
while(slow!=fast){
slow=slow->next;
fast=fast->next->next;
}
i=0;
slow=slow->next;
fast=fast->next->next;
while(slow!=fast){
i++;
slow=slow->next;
fast=fast->next->next;
}
cout<<i;
}
void deletereelem(Linklist &L){//删除单链表中的重复元素
Linklist p,q,r;
p=L->next;
while(p){
q=p->next;
r=p;
while(q){
if(p->data==q->data){
r->next=q->next;
delete q;
q=r;
}
else{
r=r->next;
}
q=q->next;
}
p=p->next;
}
p=NULL;
}
void findloopPort(Linklist &L){//给出环的入点方法1
Linklist slow,fast,f;
int i;
slow=L->next;
f=L;
fast=L->next->next;
while(slow!=fast){
slow=slow->next;
fast=fast->next->next;
}
while(f!=slow){
f=f->next;
slow=slow->next;
}
cout<<f->data;
}
void FindLoopPort(Linklist head){//给出环的入点方法2
Linklist slow = head,fast = head;
while ( fast && fast -> next )
{
slow = slow -> next;
fast = fast -> next -> next;
if ( slow == fast ) break ;
}
if (fast == NULL || fast -> next == NULL)
return ;
slow = head;
while (slow != fast)
{
slow = slow -> next;
fast = fast -> next;
}
cout<<slow->data;
}
//扩展问题:两个链表都不存在环,如果相交,给出相交的第一个点。
void judgeconnect(Linklist L1,Linklist L2){//判断两个链表是否相交,并求相交的点----方法一
Linklist p1,p2;
lengthList(L1);
lengthList(L2);
p1=L1->next;
p2=L2->next;
while(p1){
p1=p1->next;
}
while(p2){
p2=p2->next;
}
if(p2==p1){
cout<<"两个链表相交";
}
p1=L1->next;
p2=L2->next;
for(int i=1;i<(L1->data-L2->data);i++)//默认L1是长链,此处也可以比较一下
p1=p1->next;
while(p1!=p2){
p1=p1->next;
p2=p2->next;
}
cout<<p1->data;
}
void Judgecontact(Linklist L1,Linklist L2){//判断两个链表是否相交,并求相交的点----方法二
Linklist p1=L1->next;
while(p1){
p1=p1->next;
}
p1=L1->next;
if(judgement(L2)){
findloopPort(L2);
}
else
;
}
void lenghcircle(Linklist L2){//求链表的长度
//比较简单,就是把上面的求环的长度+上面给环入点时可以同时求出的入点到头指针的距离
}
int main()
{
Linklist L;
createList(L);
circle(L,3);
// FindLoopPort(L);
findloopPort(L);
// lengthcircle(L);
// display(L);
// deletereelem(L);
// display(L);
// NIndex(L);
// BulidListLoop(L,4);
// middle(L);
// cout<<judgement(L);
// ReverseList(L);
return 0;
}