链表的有关操作

/*///
随机产生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;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值