2.2.2笔记-线性表合并

数据结构笔记三

            把顺序线性表合并,在教材P26中有个算法2.7。算法2.7的大致意思是:已知顺序线性表La和Lb的元素按值非递减排列,然后要求归并La和Lb得到新的顺序线性表Lc,Lc的元素也要按值非递减排列。下面程序的时间复杂度O(La.length+Lb.length)。

备注:若以线性表表示集合并进行集合的各种运算,应先对表中元素进行排序。(教材P26)

源代码

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define list_init_size 10
#define list_increment 2
#define ok 1
#define error 0
typedef int elemtype;
typedef int status;

struct sqlist{
	elemtype *elem;//存储空间基址
	int length;//当前长度
	int listsize;//当前分配的存储容量(以sizeof(elemtype)为单位)
};
void initlist(sqlist &l){
//操作结果:构造一个空的顺序线性表l
	l.elem=(elemtype *)malloc(list_init_size*sizeof(elemtype));
	if(!l.elem)//存储分配失败
		exit(overflow);
	l.length=0;//空表长度为0
	l.listsize=list_init_size;//初始存储容量
}
status listinsert(sqlist &l,int i,elemtype e){
	//初始条件:顺序线性表l已存在,1≤i≤listlength(l)+1
	//操作结果:在l中第i个位置之前插入新的数据元素e,l的长度加1
	elemtype *newbase,*q,*p;
	if(i<1||i>l.length+1)
		return error;
	if(l.length==l.listsize)//当前存储空间已满,增加分配,,修改
	{
		newbase=(elemtype *)realloc(l.elem,(l.listsize+list_increment)*sizeof(elemtype));
		if(!newbase)//存储分配失败
			exit(overflow);
		l.elem=newbase;//新基址赋给l.elem
		l.listsize+=list_increment;//增加存储容量
	}
	q=l.elem+i-1;//q为插入位置
	for(p=l.elem+l.length-1;p>=q;--p)//插入位置之后的元素后移(由表尾元素开始移)
		*(p+1)=*p;
	*q=e;//插入e
	++l.length;//表长增1
	return ok;
}
void mergelist(sqlist la,sqlist lb,sqlist &lc){
//已知顺序线性表la和lb的元素按值非递减排列
//归并la和lb得到新的顺序线性表lc,lc的元素也按值非递减排列(不改变表la和lb)
   elemtype *pa,*pa_last,*pb,*pb_last,*pc;
   pa=la.elem;//pa指向表la的第1个元素
   pb=lb.elem;//pb指向表lb的第1个元素
   lc.listsize=lc.length=la.length+lb.length;//不用initlist()创建空表lc
   pc=lc.elem=(elemtype *)malloc(lc.listsize*sizeof(elemtype));//分配所需空间
   if(!lc.elem)//存储分配失败
	   exit(overflow);
pa_last=la.elem+la.length-1;//pa_last指向表la的最后一个元素
pb_last=lb.elem+lb.length-1;//pb_last指向表lb的最后一个元素
while(pa<=pa_last&&pb<=pb_last)//表la和表lb均有元素没有归并
{//归并
	if(*pa<=*pb)//表la的当前元素不大于表lb的当前元素
		*pc++=*pa++;//将pa所指单元的值赋给pc所指单元后,pa和pc分别+1
	else
		*pc++=*pb++;//将pb所指单元的值赋给pc所指单元后,pb和pc分别+1
}
//以下两个while循环只会有一个被执行
while(pa<=pa_last)//当la中的元素全部归并,插入la的剩余元素
   *pc++=*pa++;
while(pb<=pb_last)//当lb中的元素全部归并,插入lb的剩余元素
	*pc++=*pb++;
}
void listtraverse(sqlist &l,void(*visit)(elemtype&)){
//初始条件:顺序线性表l已存在
//操作结果:依次对l的每个数据元素调用函数visit() visit()的形参加'&',表明可通过visit()改变元素的值 
	elemtype *p=l.elem;//p指向第一个元素
	int i;
	for(i=1;i<=l.length;i++)//从表l的第一个元素到最后1个元素
		visit(*p++);//对每个数据元素调用visit()
	printf("\n");

}
void print1(elemtype &c){
//以十进制整型的格式输出元素的值(设c为 引用类型)
	//此处的引用只是为了满足listtraverse函数复用的需要,而对于listtraverse函数的第二个参数中真正用到&的是dbl()函数
	printf("%d ",c);
}
void main(){
	sqlist la,lb,lc;
	int j;
	initlist(la);
	for(j=1;j<=5;j++)//在表la中插入5个元素,依次为1、2、3、4、5
		listinsert(la,j,j);
	printf("la= ");//输出表la的内容
	listtraverse(la,print1);
	initlist(lb);
	for(j=1;j<=5;j++)//在表lb中插入5个元素,依次为2、4、6、8、10
		listinsert(lb,j,2*j);
	printf("lb= ");//输出表lb的内容
	listtraverse(lb,print1);
	mergelist(la,lb,lc);//由按非递减排列的表la、lb得到按非递减排列的表lc
	printf("lc= ");//输出表lc的内容
	listtraverse(lc,print1);
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值