/*///
随机产生n个整数,进行单链表操作
///*/
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <iomanip>
using namespace std;
#define NUMBER 10
/
//数据结构定义
typedef struct list{
int data;
struct list *next;
}node,*Linklist;
/
//随机产生数据,建立单链表
void create_L(Linklist &L,int n)
{
int i;
Linklist newnode,p;
L=new node;
if(L==NULL)
cout<<"Failure!";
else
{
p=L;
for(i=0;i<n;i++)
{
newnode=new node;
newnode->data=i*10+rand()%10; //从小到大生成随机数
p->next=newnode;
p=newnode;
}//for
p->next=NULL;
}//else
}
//有序插入
void insert_L1(Linklist &L,int n)
{
Linklist q,p,r;
r=new node; //创建新结点
q=L; //q为头结点
p=L->next; //p为首元结点
while(p&&p->data<n) //找到待插位置
{
q=p;
p=p->next;
} //while
r->data=n;
r->next=p;
q->next=r; //插入r
cout<<"插入成功!"<<endl; //输出
}
//固定位置插入
void insert_L2(Linklist &L,int i,int e)
{
Linklist p,r;
int j=0;
p=L; //p为头结点
while(p&&j<i-1) //找到插入位置前一个结点
{
p=p->next;
++j;
} //while
if(!p||j>i-1) //i过大或过小
{
cout<<"该位置无法插入!"<<endl;
return ;
} //if
r=new node;
r->data=e;
r->next=p->next;
p->next=r; //插入
cout<<"插入成功!"<<endl;
}
//删除相同数
void delete_L1(Linklist &L)
{
Linklist p,q; //q为前一个指针,p为后一个指针
q=L->next;
p=q->next;
while(p)
{
if(q->data!=p->data) //元素重复
{
q=p;
p=p->next;
} //if
else
{
q->next=p->next;
free(p);
p=q->next;
} //else
} //while
}
//删除区间数
void delete_L2(Linklist &L,int mink,int maxk)
{
Linklist q,p,r;
q=L; //q为头结点
p=L->next; //p为首元结点
if(!p||p->data>maxk) //空链表或区间数过小
{
cout<<"空链表或区间数过小!"<<endl;
return ;
} //if
while(p&&p->data<mink) //找到待删位置
{
q=p;
p=p->next;
} //while
if(!p) //区间数过大
{
cout<<"区间数过大!"<<endl;
return ;
} //if
while(p&&p->data<=maxk) //删除区间数
{
r=p; //r保存p
p=p->next;
free(r); //删除r
} //while
q->next=p; //连接
}
//删除指定位置
void delete_L3(Linklist &L,int pos)
{
Linklist q,p; //p为q下一个结点
q=L;
p=L->next;
int i=0;
while(p&&i<pos-1) //找到待删位置
{
i++;
q=p;
p=p->next;
} //while
if(!p||i>pos-1) //pos过大或过小
{
cout<<"不存在该位置!"<<endl;
return ;
} //if
q->next=p->next; //删除结点
free(p);
}
//链表并集(原空间)
void merge_L1(Linklist &LA,Linklist &LB,Linklist &LC)
{
Linklist p,q,r;
p=LA->next;
q=LB->next;
r=LC=LA; //用LA链表头结点作为LC链表头结点
while(p&&q)
{
if(p->data<q->data)
{
r->next=p;
r=p;
p=p->next;
} //if
else if(p->data>q->data)
{
r->next=q;
r=q;
q=q->next;
} //else if
else //有相同元素时只加入LA中的元素
{
r->next=p;
r=p;
p=p->next; //p后移
q=q->next; //q后移
} //else
} //while
r->next=p?p:q; //将余下的链表放入LC
free(LB); //释放LB空间
}
//链表并集(申请空间)
void merge_L2(Linklist &LA,Linklist &LB,Linklist &LC)
{
Linklist p,q,r,newnode;
p=LA->next;
q=LB->next;
LC=new node; //创建LC
r=LC; //r为LC头结点
while(p&&q)
{
newnode=new node; //创建新结点
if(p->data<q->data)
{
newnode->data=p->data;
p=p->next;
} //if
else if(p->data>q->data)
{
newnode->data=q->data;
q=q->next;
} //else if
else //两数相等时,存入p的data值,p、q都后移
{
newnode->data=p->data;
p=p->next;
q=q->next;
} //else
r->next=newnode; //连接新结点
r=newnode;
} //while
if(!p)
p=q;
while(p) //剩余链表加入LC
{
newnode=new node;
newnode->data=p->data;
r->next=newnode;
r=newnode;
p=p->next;
} //while
r->next=NULL; //最后一个结点指向NULL
}
//链表交集
void comp_L(Linklist &LA,Linklist &LB,Linklist &LC)
{
Linklist p,q,r,newnode;
p=LA->next;
q=LB->next;
LC=new node; //创建LC
r=LC; //r为LC头结点
while(p&&q)
{
if(p->data<q->data)
p=p->next;
else if(p->data>q->data)
q=q->next;
else //两数相等时,存入p的data值,p、q都后移
{
newnode=new node; //创建新结点
newnode->data=p->data;
p=p->next;
q=q->next;
r->next=newnode; //连接新结点
r=newnode;
} //else
} //while
r->next=NULL;
}
//链表差集
void differ_L(Linklist &LA,Linklist &LB)
{
Linklist p,q,r;
r=LA;
p=LA->next;
q=LB->next;
while(p&&q)
{
if(p->data<q->data)
{
r=p;
p=p->next;
}
else if(p->data>q->data)
q=q->next;
else //元素相同
{
r->next=p->next; //删除
free(p); //释放p结点的空间
p=r->next;
} //else
} //while
}
//拆分奇偶项
void device_L1(Linklist &L,Linklist &LA,Linklist &LB)
{
Linklist p,s,r;
int i=0;
p=L->next; //p指向L第一个结点
LA=new node; //为LA头结点分配空间
s=LA; //s指向LA头结点
LB=new node; //为LB头结点分配空间
r=LB; //r指向LB头结点
while(p!=NULL)
{
i++;
if(i%2==1) //将L中数据为奇数项的结点连到LA上
{
s->next=p;
s=p;
} //if
if(i%2==0) //将L数据为偶数项的结点连到LB上
{
r->next=p;
r=p;
} //if
p=p->next; //后移
}//while
s->next=NULL; //结尾指向NULL
r->next=NULL; //结尾指向NULL
}
//拆分奇偶数
void device_L2(Linklist &L,Linklist &LA,Linklist &LB)
{
Linklist p,s,r;
p=L->next; //p指向L第一个结点
LA=new node; //为LA头结点分配空间
s=LA; //s指向LA头结点
LB=new node; //为LB头结点分配空间
r=LB; //r指向LB头结点
while(p!=NULL)
{
if(p->data%2==1) //将L中数据为奇数的结点连到LA上
{
s->next=p;
s=p;
}
if(p->data%2==0) //将L数据为偶数的结点连到LB上
{
r->next=p;
r=p;
}
p=p->next; //后移
}//while
s->next=NULL; //结尾指向NULL
r->next=NULL; //结尾指向NULL
}
//链表逆置
void change_L(Linklist L)
{
Linklist p,q,r;
int i=0;
p=L->next; //p为首元结点
if(!p||!p->next) //L为空或只有一个结点
return ;
r=q=NULL; //r和q初始化为NULL
while(p)
{
q=p->next; //q保存p后一个指针
p->next=r; //逆置
r=p; //r后移
p=q; //p后移
} //while
cout<<"输出逆置链表为:"<<endl;
while (r!=NULL) //头结点改变,逆置后从r开始
{
i++;
cout<<"-->"<<setw(4)<<i<<":"<<setw(4)<<r->data;
r=r->next;
if(i%5==0)
cout<<endl;
}//while
cout<<"-->NULL"<<endl;
}
//输出单链表
void print_L(Linklist L)
{
int i=0;
Linklist p;
p=L->next; //p为首元结点
while (p!=NULL)
{
i++;
cout<<"-->"<<setw(4)<<i<<":"<<setw(4)<<p->data;
p=p->next;
if(i%5==0) //一行5个数
cout<<endl;
}//while
cout<<"-->NULL"<<endl;
}
//主函数
int main()
{
Linklist la,lb,lc; //链表
int num,n,k;
srand(time(0)); //随机数初始化
do{
cout<<" 单链表操作 "<<endl;
cout<<"*********************************"<<endl;
cout<<" 1.建立-顺序建立 "<<endl;
cout<<" 2.插入-有序插入 "<<endl;
cout<<" 3.插入-位置插入 "<<endl;
cout<<" 4.删除-重复元素 "<<endl;
cout<<" 5.删除-指定区间 "<<endl;
cout<<" 6.删除-指定位置 "<<endl;
cout<<" 7.合并-原表空间 "<<endl;
cout<<" 8.合并-申请空间 "<<endl;
cout<<" 9.求交-链表交集 "<<endl;
cout<<" 10.求LA链表差集 "<<endl;
cout<<" 11.分拆-奇偶项 "<<endl;
cout<<" 12.分拆-奇偶数 "<<endl;
cout<<" 13.逆置 "<<endl;
cout<<" 14.输出 "<<endl;
cout<<" 0.退 出 "<<endl;
cout<<"*********************************"<<endl;
cout<<"请输入0-14中的一个数字:";
cin>>num;
cout<<endl;
switch(num)
{
case 0:
break;
case 1:
cout<<"输入链表长度:";
cin>>n;
create_L(la,n);
break;
case 2:
cout<<"输入要插入的数:";
cin>>n;
insert_L1(la,n);
cout<<"输出链表为:"<<endl;
print_L(la);
break;
case 3:
cout<<"输入待插入的位置:";
cin>>n;
cout<<"输入待插入的数值:";
cin>>k;
insert_L2(la,n,k);
cout<<"输出链表为:"<<endl;
print_L(la);
break;
case 4:
delete_L1(la);
cout<<"去重成功!"<<endl;
cout<<"输出链表为:"<<endl;
print_L(la);
break;
case 5:
cout<<"删除区间为:"<<endl;
cin>>n>>k;
delete_L2(la,n,k);
cout<<"输出链表为:"<<endl;
print_L(la);
break;
case 6:
cout<<"删除位置为:"<<endl;
cin>>n;
delete_L3(la,n);
cout<<"输出链表为:"<<endl;
print_L(la);
break;
case 7:
cout<<"输入链表LA长度:"<<endl;
cin>>n;
create_L(la,n);
print_L(la);
cout<<"输入链表LB长度:"<<endl;
cin>>k;
create_L(lb,k);
print_L(lb);
merge_L1(la,lb,lc);
cout<<"合并链表为:"<<endl;
print_L(lc);
break;
case 8:
cout<<"输入链表LA长度:"<<endl;
cin>>n;
create_L(la,n);
print_L(la);
cout<<"输入链表LB长度:"<<endl;
cin>>k;
create_L(lb,k);
print_L(lb);
merge_L2(la,lb,lc);
cout<<"合并链表为:"<<endl;
print_L(lc);
break;
case 9:
cout<<"输入链表LA长度:"<<endl;
cin>>n;
create_L(la,n);
print_L(la);
cout<<"输入链表LB长度:"<<endl;
cin>>k;
create_L(lb,k);
print_L(lb);
comp_L(la,lb,lc);
cout<<"链表交集为:"<<endl;
print_L(lc);
break;
case 10:
cout<<"输入链表LA长度:"<<endl;
cin>>n;
create_L(la,n);
print_L(la);
cout<<"输入链表LB长度:"<<endl;
cin>>k;
create_L(lb,k);
print_L(lb);
differ_L(la,lb);
cout<<"链表差集为:"<<endl;
print_L(la);
break;
case 11:
cout<<"输入链表长度:";
cin>>n;
create_L(la,n);
device_L1(la,lb,lc);
cout<<"输出单链表LA:"<<endl;
print_L(lb);
cout<<"输出单链表LB:"<<endl;
print_L(lc);
break;
case 12:
cout<<"输入链表长度:";
cin>>n;
create_L(la,n);
device_L2(la,lb,lc);
cout<<"输出单链表LA:"<<endl;
print_L(lb);
cout<<"输出单链表LB:"<<endl;
print_L(lc);
break;
case 13:
change_L(la);
break;
case 14:
cout<<"输出链表为:"<<endl;
print_L(la);
break;
} //switch
system("pause"); //暂停
} while(num>0&&num<15);
return 0;
} //main
以上插入采取尾插法,若使用头插法,则:
void create_L(link &L,int n)
{
int i;
link newnode;
L=new node;
L->next=NULL; //结尾指向NULL
if(L==NULL)
cout<<"Failure!";
else
{
for(i=0;i<n;i++)
{
newnode=new node;
newnode->data=i*10+rand()%10;
newnode->next=L->next; //加在头结点后
L->next=newnode;
}//for
}//else
}//create
算法复习:
单链表实现就地逆置
void reverse_l(linklist &l)
{
p=l->next;
if(!p||!p->next)
return ;
q=p->next;
p->next=NULL;
p=q;
while(p)
{
q=p->next;
p->next=l->next;
l->next=p;
p=q;
}
}
void reverse_l(linklist &l)
{
linklist p,s,r;
p=l->next;
s=NULL;
if(!p||!p->next)
return ;
while(p)
{
r=p->next;
p->next=s;
s=p;
p=r;
}
}
删除表中所有值相同的多余元素
void delete_l(linklist &l)
{
p=l->next;
if(!p)
return ;
q=p->next;
while(q)
{
if(p->data!=q->data)
{
p=q;
q=q->next;
}
else
{
p->next=q->next;
free(q);
q=p->next;
}
}
}