顺序表_归并顺序表举例

该博客介绍了一个C++实现的顺序线性表归并排序算法。通过两个已排序的顺序表La和Lb,利用while循环和条件判断进行元素比较,将较小的元素依次插入到新的顺序表Lc中,最终得到一个按非递减顺序排列的Lc。示例代码展示了如何初始化、插入元素以及输出线性表内容。

顺序表的归并举例

说明

  • 已知:顺序线性表La和Lb的元素按值非递减排序
  • 要求:归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排序(不改变表La和表Lb)

以下内容保存在algo2-1.cpp

/*
 * 时间:2021.01.30
 * 内容:实现算法2.7
 * 算法2.7:
 * 已知顺序线性表La和Lb的元素按值非递减排序
 * 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排序(不改变表La和表Lb)
 */

#include "c1.h"

typedef int ElemType;	// 定义ElemType为整型
#include "c2-1.h"	// 线性表的顺序存储结构
#include "bo2-1.h"	// 线性表顺序存储结构的基本操作
#include "fun2-2.h"	//  包括qual(),comp(),print(),print1()和print2()函数

void MergeList(SqList La, SqList Lb, SqList &Lc)	// 算法2.7
{// 已知顺序线性表La和Lb的元素按值非递减排序
 // 归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排序(不改变表La和表Lb)

	ElemType * pa, *pa_last, *pb, *pb_last, *pc;
	
	pa = La.elem;	// pa指向表La的第一个元素
	pb = Lb.elem;	// pb指向表Lb的第一个元素

	Lc.listsize  = Lc.length = Lc.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)	// 表Lb中的元素全部归并
	{
		* pc++ = * pa++;	// 插入La中的剩余元素
	}

	while(pb <= pb_last)	// 表La中的元素全部归并
	{
		* pc++ = * pb++;	// 插入Lb的剩余元素
	}

	return;
}

void main()
{
	SqList La, Lb, Lc;
	int j;

	InitList(La);	// 创建空表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);	// 创建空表Lb
	for (j = 1; j <= 5; j++)
	{
		ListInsert(Lb, j, 2 * j);	// 在表Lb中插入5个元素,依次为2,4,6,8,10
	}
	printf("Lb = ");	// 输出表Lb的内容
	ListTraverse(Lb, print1);

	MergeList(La, Lb, Lc);	// 由按非递减排序的表La,Lb得到按非递减排序的表Lc
	printf("Lc = ");	// 输出表Lc的内容
	ListTraverse(Lc, print1);	// 输出表Lc的内容

	return;
}

<think>我们正在讨论两个有序链表合并的含义。根据之前的引用,我们可以看到多个来源都描述了合并两个有序链表的方法和含义。 含义解释: 合并两个有序链表是指将两个已经按特定顺序(通常是升序或降序)排列的链表,合并为一个新的有序链表。新链表中的节点来自原先的两个链表,且保持原有的排序关系。 关键点: 1. 输入:两个链表,每个链表中的元素已经有序(假设为升序)。 2. 输出:一个合并后的新链表(或者有时要求在原链表上合并,不占用额外空间),新链表中的元素也是升序排列的。 3. 要求:合并后的链表必须保持有序性,即新链表中的每个节点都按照顺序连接。 举例说明: 假设有两个链表: 链表1:1 -> 3 -> 5 链表2:2 -> 4 -> 6 合并后的链表:1 -> 2 -> 3 -> 4 -> 5 -> 6 合并的意义: 在实际应用中,合并操作常用于需要将多个有序数据集合合并为一个有序集合的场景。例如: - 数据库系统中合并多个有序的结果集。 - 归并排序中的合并步骤。 - 合并多个有序的文件。 合并的方法: 根据引用的描述,常见有两种方法: 1. 迭代法:使用循环,每次比较两个链表当前节点的,将较小的节点连接到新链表上,然后移动该链表的指针。直到其中一个链表为空,再将另一个链表的剩余部分连接到新链表尾部。这种方法时间复杂度为$O(n+m)$,其中$n$和$m$分别为两个链表的长度。[^1][^2][^3][^4] 2. 递归法:递归地比较两个链表的头节点,将较小节点作为合并后链表的头,然后递归地合并剩余部分。 注意:合并过程中,如果两个链表有相同的节点,通常按照原顺序合并(即可以保留重复)。 根据引用[3],有时要求不占用新的存储空间,即原地合并,这时可以将节点重新链接而不创建新节点。 总结:合并两个有序链表是一个基础且重要的链表操作,核心在于有序性的保持和高效合并。 §§相关问题§§ 1. 迭代法和递归法在合并两个有序链表时各有什么优缺点? 2. 如果两个链表都是降序排列,如何合并成一个降序链表? 3. 如何合并多个(大于两个)有序链表? 4. 在合并有序链表时,如何处理重复元素? 5. 如果不允许使用额外空间(原地合并),如何实现两个有序链表的合并? </think>### 两个有序链表合并的含义 合并两个有序链表是指将两个**已按特定顺序排列的链表**,通过节点重组整合成一个**新的有序链表**的过程。新链表需严格保持原有排序规则(通常为升序或降序),且包含所有原始元素。核心要点如下: 1. **输入特征** - 两个链表各自节点已排序(如 `1→3→5` 和 `2→4→6`) - 排序规则相同(均升序或均降序) 2. **输出要求** - 新链表节点完全有序(如合并结果 `1→2→3→4→5→6`) - 新链表由原节点重组而成(不创建新节点) - 时间复杂度为 $O(n+m)$($n,m$为链表长度)[^1][^3] 3. **核心操作原理** 通过**双指针遍历**比较节点: ```mermaid graph LR A[链表1头节点] --> C{比较节点} B[链表2头节点] --> C C -->|小者| D[链接到新链表] D --> E[指针后移] E --> C C -->|某链表空| F[链接另一链表剩余部分] ``` 4. **技术意义** - **数据库合并**:合并有序查询结果集[^1] - **文件排序**:归并排序中的关键步骤 - **资源优化**:避免全量重排序,时间复杂度最优[^4] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值