数据结构 线性表的两种合并方式Union() MergeList()

首先是定义一个叫student的结构体 有num和next 一个整型变量  一个指针

typedef struct student
	{                                      //定义结构体 
		int num;                                      
		student *next;
	}student,*stu;                
	

书上第一种合并方式 Union

void Union(stu &list1,stu list2)                             //第一种合并  将 list2元素逐个插入到kist1中 且 不重复(默认递增输入) 
{
	int temp;
		int l1_len = ListLength(list1); 
		int l2_len = ListLength(list2);
		
		for(int i =1;i<=l2_len;i++)
		{
			temp = GetElem(list2,i);                       //拿到list2第i个元素的值给temp 
			if(!LocateElem(list1,temp))                   //再到list1中去找有没有相同的  没有的话就把元素插到list1里面去 
			{	
				Insert(list1,temp); 
			}
		}
}

第二种方式 MergeList 

stu MergeList(stu list1,stu list2,stu &listc)                //第二种合并  直接合并成新链表listc (默认递增输入) 
{	int i = 1,j = 1,k = 0;
	int ai,bj,La_len,Lb_len;
	La_len = ListLength(list1);
	Lb_len = ListLength(list2);
	while((i<=La_len)&&(j<=Lb_len))                            //i j 都小于长度时 
	{
		ai = GetElem(list1,i);
		bj = GetElem(list2,j);
		if(ai<=bj)
		{
			Insert(listc,ai);
			++i;
		}
		if(ai>bj) 
		{
			Insert(listc,bj);                        //循环出问题1   
			++j;
		}
	}
	while(i<=La_len)                                            //只剩下 list1了  就直接插入 
	{
		ai = GetElem(list1,i);
		Insert(listc,ai);
		++i;
	} 
	while(j<=Lb_len)                                             //同上 只剩list2 
	{
		bj = GetElem(list2,j);
		Insert(listc,bj);
		++j;
	}
	return listc;
} 

主函数及测试
	int main()
	{
		stu list1,list2,listc,t;
		printf("请输入list1:\n");                                   //逐个输入 都要回车 
		list1 = CreatList();
		printf("list2:\n");
		list2 = CreatList();
		listc = InitList(listc);
    	listc = MergeList(list1,list2,listc);
		Union(list1,list2); 
//		MergeList(list1,list2,listc);                               //MergeList示例 
 		for(t = list1->next;t!=NULL;t = t->next)
		{	
			printf("%d\n",t->num);
			
		}
		return 0;
	} 

下面代码贴在结构体后面可以直接测试

stu InitList(stu L)
{
	stu head = (stu)malloc(sizeof(student));               //初始化空链表 
	head->next = NULL;
	head->num =0;
	L = head;
	return L;
}
stu CreatList()                                                //创建链表              
	{
		stu head,t;
		head = (stu)malloc(sizeof(student));
		head->num = 0;
		head->next = NULL;
		t = head;                                          //让t指针指向head结点 
		int temp;
		while(scanf("%d",&temp)!=EOF)                      //EOF文本读入结束标志  也可以手动输入ctril+z结束 
		{
			stu p;
			p = (stu)malloc(sizeof(student));               //申请空间 
			p->num = temp;                                    
			t->next = p;                                     //t(正指向head)的next指针指向新的结点 
			t = p;                                           //让t指向现在的p结点  t 始终指向最后一个结点 
		}
		t->next = NULL;                                     //最后把t所指结点的next指针放空  否则后面判断p->next==NULL出错 
		return head;                                        //最后返回head  指向链表的头结点 
	}
	
stu del(stu L,int x)
	{
		stu pre = L,p = L->next;    //pre永远指向p前面的结点  间隔一个元素 
		while(p->num!=x&&p->next!=NULL)        //一直使用p找到要删除的元素 p指向删除元素时pre指向前驱结点 
		{
			pre = p;                                     //pre 指向下一个结点 因为p指向的就是pre的下一个结点  
			p = p->next;                                  //p指向下一个结点 
		}
		pre->next = p->next;                             //pre指向p->next所指的元素  
		free(p);
		return L;
	}
	
int ListLength(stu L)                                 //求链表长度 
	{
		int len = 0;
		stu p = L;
		while(p->next!=NULL)
		{
			p = p->next;
			len++;
		}
		return len;
	}
	
int GetElem(stu L,int n)                                //获取第n个元素的数据 
	{
		if(L->next==NULL){                              //判空 
			return 0;
		} 
		int num = 0;
		stu p = L;                                      //指向L的头 
		for(int j =1;j<=n;j++)                           //注意循环1-n 
		{
			p = p->next;
		}
		num = p->num;                                  
		return num;
	} 
	
	int Compare(int a,int b)                        //比较函数 
	{
	if(a>b)
	{
	return 1;	
	}
	if(a<b)
	{
		return -1;
	}
	if(a==b)
	{
		return 0;
	}
}
	
int  LocateElem(stu L,int x)                         //查找链表L中是否有和x相同的数据 
{
	if(L->next==NULL){
		return 0;
	}
	stu p =L;
	for(int i =1;i<=ListLength(L)+1;i++)
	{
		if(Compare(p->num,x)==0)
		{
			return 1;                               //有相同的返回1 
		}
		
		p = p->next;	
	}
	 return 0;
	
}

stu Insert(stu &L,int x){                                //插入  按照递增顺序 
	stu pre = L,p = L->next;
	if(L->next!=NULL)                                     //L是否为空 
	{
	while(p->num<x&&p->next!=NULL)          //直到找到比x大的元素此时pre指向前一个  p指向比x大的那个   或者到最末尾  
	{
		pre = p;
		p = p->next;
	}
	pre = pre->next;                                      //pre指向前一个 
	stu t;
	t = (stu)malloc(sizeof(student));
	t->num = x;
	t->next = pre->next;                                  //新节点的next指向原本pre->next指向的元素  (插进去了) 
	pre->next = t;                                        //最后再把pre->next指向新节点就行 
	return L;
	}
	else                                                  //如果链表为空的话  就直接插入 
	{
		stu t;
		t = (stu)malloc(sizeof(student));
		t->num = x;
		t->next = NULL;
		L->next = t;
		return L;
	}                                                  
}



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值