线性表的应用【线性表的合并】和【顺序有序表的合并】

2.6、线性表的应用

2.6.1、线性表的合并

问题描述:
  • 已知两个集合A和B,现要求一个新的集合 A = A ∪ B A=A∪B A=AB。例如,设 A = ( 7 , 5 , 3 , 11 ) A = (7, 5, 3, 11) A=(7,5,3,11) B = ( 2 , 6 , 3 ) B = (2, 6, 3) B=(2,6,3)合并后 A = ( 7 , 5 , 3 , 11 , 2 , 6 ) A = (7, 5, 3, 11, 2, 6) A=(7,5,3,11,2,6)
算法步骤:
  • 分别获取La表长m和Lb表长n
  • 从Lb中第一个元素开始,循环n次执行以下操作:
    • 从Lb中查找第i(1 <= i <= n)个数据元素赋给e
    • 在La中查找元素e,如果不存在,则将e插在表La的最后
线性表的合并
void MergeList(List &La, List Lb) {
  // 将所有在线性表Lb但不在La中的数据元素插入到La中
  m = ListLength(La); n = ListLength(Lb);				// 求线性表的长度
  for (i = 0; i <= n; i++) {
    GetElem(Lb, i, e);													// 取Lb中第i个数据元素赋给e
    if (!LocateElem(La, e));										// La中不存在和e相同的数据元素
      ListInsert(La, ++m, e);										// 将e插在La的最后
  }
}
C语言实现:

2.6.2、顺序有序表的合并

问题描述:
  • 已知线性表La和Lb中的元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列 L a = ( 1 , 7 , 8 ) La = (1, 7, 8) La=(1,7,8) L b = ( 2 , 4 , 6 , 8 , 10 , 11 ) Lb = (2, 4, 6, 8, 10, 11) Lb=(2,4,6,8,10,11)合并后为 L c = ( 1 , 2 , 4 , 6 , 7 , 8 , 8 , 10 , 11 ) Lc = (1, 2, 4, 6, 7, 8, 8, 10, 11) Lc=(1,2,4,6,7,8,8,10,11)
算法步骤:
  • 创建一个表长为m + n的空表LC
  • 指针pc初始化,指向LC的第一个元素
  • 指针pa和pb初始化,分别指向LA和LB的第一个元素
  • 当指针pa和pb均未到达相应表尾时,则依次比较pa和pb所指向的元素值,从LA或LB中摘取元素值较小的结点插入到LC的最后
  • 如果pb已达到LB的表尾,依次将LA的剩余元素插入LC的最后
  • 如果pa已到达LA的表尾,依次将LB的剩余元素插入LC的最后
算法描述:
void MergeList_Sq(SqList LA, SqList LB, SqList LC)
{ // 已知顺序表LA和LB的元素按值非递减排列
  // 归并LA和LB得到新的顺序有序表LC,LC的元素也按值非递减排列
  LC.length = LA.length + LB.length;								// 先表长为待合并两表的长度之和
  LC.elem = new ELemType[LC.length];								// 为合并后的新表分配一个数组空间
  pc = LC.elem;																			// 指针pc指向新表的第一个元素
  pa = LA.elem;				 pb = LB.elem;								// 指针pa和pb的初值分别指向两个表的第一个元素
  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) *pc++ = *pa++;									// 依次摘取两个表中值较小的结点插入到LC的最后
    else *pc++ = *pb++;
  }
  while (pa <= pa_last) *pc++ = *pa++;							// LB已到达表尾,依次将LA的剩余元素插入到LC的最后
  while (pb <= pb_last) *pc++ = *pb++;							// LA已到达表尾,依次将LB的剩余元素插入到LC的最后
}
复杂度分析:
  • 时间复杂度: 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))

2.6.3、链表有序表的合并

问题描述:
  • 已知线性表La和Lb中的元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列 L a = ( 1 , 7 , 8 ) La = (1, 7, 8) La=(1,7,8) L b = ( 2 , 4 , 6 , 8 , 10 , 11 ) Lb = (2, 4, 6, 8, 10, 11) Lb=(2,4,6,8,10,11)合并后为 L c = ( 1 , 2 , 4 , 6 , 7 , 8 , 8 , 10 , 11 ) Lc = (1, 2, 4, 6, 7, 8, 8, 10, 11) Lc=(1,2,4,6,7,8,8,10,11)
算法步骤:
  • 指针pa和pb初始化,分别指向LA和LB的第一个结点
  • LC的结点取值为LA的头结点
  • 指针pc初始化,指向LC的头结点
  • 当指针pa和pb均未到达相应表尾时,则依次比较pa和pb所指的元素值,从LA或LB中摘取元素值比较小的结点插入到LC的最后
  • 将非空列表的剩余段插入到pc所指结点之后
  • 释放LB的头结点
算法描述:
void MergeList_L(LinkList &LA, LinkList &LB, LinkLIst &LC)
{ // 已知单链表LA和LB的元素按值非递减排列
  // 归并LA和LB得到新的单链表LC,LC的元素也按值非递减排列
  pa = LA->next;pb = LB->next;										// pa和pb的初值分别指向两个表的第一个结点
  LC = LA;																				// 用LA的头结点作为LC的头结点
  pc = LC;																				// pc的初值指向LC的头结点
  while(pa && pb)
  { // LA和LB均为到达表尾,依次摘取两表中较小的结点插入到LC的最后
    if (pa->data <= pb->data)											// 摘取pa所指结点
    {
      pc->next = pa;															// 将pa所指结点链接到pc所指结点之后
      pc = pa;																		// pc指向pa
      pa = pa->next;															// pa指向下一个结点
    }
    else 																					// 摘取pb所指结点
    {
      pc->next = pb;															// 将pb所指结点链接到pc所指结点之后
      pc = pb;																		// pc指向pb
      pb = pb->next;															// pb指向下一个结点
    }
  }																								// while
  pc->next = pa ? pa : pb;												// 将非空表的剩余段插入到pc所指结点之后
  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 ( 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))
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java小豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值