数据结构之线性表(九)——线性表的应用

两个线性表的典型应用:

  • 线性表的合并
    假设有两个线性表La和Lb分别表示两个集合A和B,现在要求一个新集合 A = A ⋃ B A=A\bigcup B A=AB,例如,
    在这里插入图片描述

  • 有序表的合并
    已知线性表La和Lb中的数据元素按值非递减有序排列,现在要求将La和Lb归并为一个线性表Lc,且Lc中的数据元素按值依旧是非递减有序排列,例如,
    在这里插入图片描述

应用一——线性表的合并

算法的输入如下,
在这里插入图片描述
输出如下,
在这里插入图片描述

算法步骤:
依次取出Lb中的每个元素,执行以下操作:

  • 在La中查找该元素
  • 如果找不到,则将其插入到La的最后(去除重复元素)

算法描述:

void union(List& La, List& Lb)
{
	La_len = ListLength(La);                  //求表La的长度
	Lb_len = ListLength(Lb);                  //求表Lb的长度
	for (i = 1; i < Lb_len; i++)              //遍历表Lb       
	{
		GetElem(Lb, i, e);                    //查找表Lb中的第i个元素e
		if (!LocateElem(La, e))               //在表La中查找有没有值等于e的元素,若有,则返回true
			ListInsert(&La, ++La_len, e);     //如果表La中没有值为e的元素,则将e加入到表La中,并且表长加1
	}
}

算法的时间复杂度: O ( L i s t L e n g t h ( L a ) ∗ L i s t L e n g t h ( L b ) ) O(ListLength(La)*ListLength(Lb)) O(ListLength(La)ListLength(Lb))




应用二——有序表的合并

算法输入如下,
在这里插入图片描述
算法输出如下,
在这里插入图片描述

算法步骤:

  • 创建一个空表Lc
  • 依次从La或Lb中“摘取”元素值较小的结点插入到Lc表的最后,直至其中一个表变空为止。
  • 继续将La或Lb其中一个表的剩余结点插入到Lc表的最后。

用顺序表实现
在这里插入图片描述
设置三个指针pa,pb,pc分别指向表La,表Lb和表Lc,依次比较pa和pb所指向的元素的值,选较小的的值加入到表Lc中,此时指向较小值的指针加1,pc指针加1,直至表La和表Lb其中一个为空,在将不为空的表的剩余元素加到表Lc的末尾。为了方便判断是否到达一个表的末尾,这里还需要加两个指针pa_last和pb_last,分别指向表La和表Lb的最后一个元素。

算法描述:

void MergeList_Sq(SqList LA, SqList LB, SqList& LC)
{
	pa = LA.elem;
	pb = LB.elem;                       //pa和pb的初值分别指向两个表的第一个元素
	LC.length = LA.length + LB.length;  //新表的长度为两个表的长度之和
	LC.elem = new ElemType[LC.length];  //为新表Lc分配一个数组空间
	pc = LC.elem;                       //pc的初值指向LC的第一个元素
	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)//两个表都非空
	{
		if (*pa <= *pb)                 //依次选取两个表中值较小的结点,加到新表LC中
			*pc++ = *pa++;
		else
			*pc++ = *pb++;
	}
	while (pa <= pa_last)               //表LB已到达末尾,将表LA中的设于元素加到LC中
		*pc++ = *pa++;
	while (pb <= pb_last)               //表LA已到达末尾,将表LB中的设于元素加到LC中
		*pc++ = *pb++;
}

该算法的时间复杂度是: O ( L i s t L e n g t h ( L a ) + L i s t L e n g t h ( L b ) ) O(ListLength(La)+ListLength(Lb)) O(ListLength(La)+ListLength(Lb)),空间复杂度是: O ( L i s t L e n g t h ( L a ) + L i s t L e n g t h ( L b ) ) O(ListLength(La)+ListLength(Lb)) O(ListLength(La)+ListLength(Lb))

用链表实现

具体步骤:
1.用La的头结点作为Lc的头结点,分别用指针pa,pb,pc来操作表La,Lb,Lc当中的结点。
在这里插入图片描述
2.比较pa和pb结点的data域的值,如图,pa指向的结点的data域的值较小,所以pc的next域存放1结点的地址,即,在这里插入图片描述
3.之后,pc指针就要往后移一位,指向1结点,并且pa指针也要往后移一位(pb指针不用移),即,在这里插入图片描述
4.再次比较pa和pb指向结点的data域值的大小,如图,2结点的值比较小,所以pc的next域存放2结点的地址,然后,将pc后移一位,pb指针后移一位,即,
在这里插入图片描述
5.重复步骤3和4的操作,直到其中一个表为空,此时将另一个表剩余部分加到Lc当中,即,
在这里插入图片描述
6.释放Lb的头结点,
在这里插入图片描述

算法描述:

void MergeList_L(LinkList& La, LinkList& Lb, LinkList& Lc)
{
	pa = La->next;
	pb = Lb->next;              //初始化pa,pb为指向表La,Lb首元结点的指针
	pc = Lc = La;               //用La的头结点作为Lc的头结点
	while (pa&&pb)              //当pa和pb不为空时
	{ 
		if (pa->data <= pb->data)   //比较pa,pb所指向结点的数据域大小
		{
			pc->next = pa;          //pc的next域指向pa(pa的data域的值较小)
			pc = pa;                //pc移到当前结点处
			pa = pa->next;          //pa向后一个结点
		}
		else
		{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	pc->next = pa ? pa : pb;        //插入剩余段
	delete Lb;                      //释放Lb的头结点
}

该算法的时间复杂度是: O ( L i s t L e n g t h ( L a ) + L i s t L e n g t h ( L b ) ) O(ListLength(La)+ListLength(Lb)) O(ListLength(La)+ListLength(Lb)),空间复杂度是: O ( 1 ) O(1) O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值