【C语言练习——合并两个有序序列】

这篇具有很好参考价值的文章主要介绍了【C语言练习——合并两个有序序列】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

第一行包含两个正整数n, m,用空格分隔; n表示第二行第一个升序序列中数字的个数; m表示第三行第二个升序序列中数字的个数
第二行包含n个整数,用空格分隔
第三行包含m个整数,用空格分隔

输出描述:

  • 输出为一行,输出长度为n+m的升序序列
  • 即长度为n的升序序列和长度为m的升序序列中的元素重新进行升序序列排列合并
输入:
5 6
1 3 5 7 9 
0 2 4 6 8 10
输出:
0 1 2 3 4 5 6 7 8 9 10

1、方法1——先合并再冒泡排序

方法1 显示利用数组开辟空间,再将两个数组合并后,通过冒泡排序算法进行排序:

  • 在C语言基础阶段中 【C语言基础5——数组(1)】4、数组作为函数参数 已经详细学过冒泡排序算法了

  • 在C语言进阶阶段中【C语言进阶11——字符和字符串函数及其模拟实现(2))7、内存操作函数】 已经详细学过库函数了

方法1的思路见下图:

【C语言练习——合并两个有序序列】

void bubble_sort(int* arr, int sz)
{
	//排序坐外面的大循环次数
	int i = 0;
	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//状态机标志位,代表数组本身元素就是从小到大排序的
		int j = 0;
		for (j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;//只要有一个地方需要排序,就置零
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		if (1 == flag)
		{//第一轮排序结果都是1,说明没有地方需要排序
			break;//直接跳出后面的循环,不需要再排序了
		}
	}
}
int main()
{
	int m = 0;//数组a的个数
	int n = 0;//数组b的个数
	int i = 0;
	int j = 0;

	scanf("%d%d", &m, &n);
	int a[1000];
	int b[1000];

	//输入第一个数组
	for (i = 0; i < m; i++)
	{
		scanf("%d", &a[i]);
	}

	//输入第二个数组
	for (j = 0; j < n; j++)
	{
		scanf("%d", &b[j]);
	}
	memcpy(a+m, b, n*4);//利用了库函数
	//可以将合并后的数组打印出来看看
	//for (int i = 0; i < m+n; i++)
	//{
	//	printf("%d ", a[i]);
	//}
	bubble_sort(a, m+n);//冒泡排序的函数,
	i = 0;
	for (i = 0; i < m + n; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

结果见下图所示:

【C语言练习——合并两个有序序列】
在【初阶数据结构与算法 1】时间复杂度与空间复杂度(1)2.3.5 练习5 中,已经详细学习过冒泡算法的时间复杂度为 O(N^2)

因此将在方法1 的基础上进行优化。

2、方法2——数组元素一一比较

将两个序列的元素一一比较,按顺序直接打印出来。方法2 的思路见下图

【C语言练习——合并两个有序序列】

int main()
{
	int m = 0;//数组a的元素个数
	int n = 0;//数组b的元素个数
	int i = 0;
	int j = 0;
	scanf("%d%d", &m, &n);
	int a[1000];//定义数组a
	int b[1000];//定义数组a

	//输入第一个数组
	for (i = 0; i < m; i++)
	{
		scanf("%d", &a[i]);
	}

	//输入第二个数组
	for (j = 0; j < n; j++)
	{
		scanf("%d", &b[j]);
	}
	i = 0;//再次初始化
	j = 0;
	while (i < m && j < n)
	{
		if (a[i]<b[j])
		{
			printf("%d ", a[i]);
			i++;
		}
		else
		{
			printf("%d ", b[j]);
			j++;
		}
	}
	if (i==m)//此时数组a的值都已经打印出来了
	{
		for(;  j< n; j++)//数组b剩下的元素想直接打印出来就行了
		{
			printf("%d ", b[j]);
		}
	}

	if (j == n)//此时数组b的值都已经打印出来了
	{
		for (; i < m; i++)//数组a剩下的元素想直接打印出来就行了
		{
			printf("%d ", a[i]);
		}
	}
	return 0;

}

结果见下图所示:

【C语言练习——合并两个有序序列】
方法2的时间复杂度为 O(m+n).

3、方法3——动态内存空间版

在C语言进阶阶段 【C语言进阶13——动态内存管理】 已经学习了动态内存开辟空间相比数组的优势了,方法3 利用动态内存空间和库函数,开辟所需空间大小,不浪费空间

方法3的思路见下图:

【C语言练习——合并两个有序序列】

//动态内存版
int main()
{
	int m = 0;//数组a的个数
	int n = 0;//shuzub的个数
	int i = 0;
	int j = 0;
	scanf("%d%d", &m, &n);
	
	int *pa = (int*)malloc((m + 1) * sizeof(int));//开辟有序序列合并的数组空间
	int *pb = (int*)malloc((n + 1) * sizeof(int));//开辟有序序列合并的数组空间
	if (pa == NULL)
	{
		perror("malloc: ");
		return;
	}
	if (pb == NULL)
	{
		perror("malloc: ");
		return;
	}
	//输入第一个数组
	for (i = 0; i < m; i++)
	{
		scanf("%d", pa+i);
	}

	//输入第二个数组
	for (j = 0; j < n; j++)
	{
		scanf("%d", pb+j);
	}
	i = 0;//再次初始化
	j = 0;
	
	while (i<m && j<n)
	{
		if (*(pa + i) < *(pb + j))
		{
			printf("%d ", *(pa + i));
			i++;
		}
		else
		{
			printf("%d ", *(pb + j));
			j++;
		}
	}
	if (i == m)//此时数组a的值都已经打印出来了
	{
		for (; j < n; j++)//数组b剩下的元素想直接打印出来就行了
		{
			printf("%d ", *(pb + j));
		}
	}

	if (j == n)//此时数组b的值都已经打印出来了
	{
		for (; i < m; i++)//数组a剩下的元素想直接打印出来就行了
		{
			printf("%d ", *(pa + i));
		}
	}
	
	free(pa);
	free(pb);
	pa = NULL;
	pb = NULL;
	return 0;
}

结果见下图所示:

【C语言练习——合并两个有序序列】


总结

C语言还需要多练习,不管自己写的代码是罗嗦了,还是太烂了,也必须要写完,大胆实现自己的想法,实现题目要求,这是最重要的一步。

第二步就是多看看别人写的代码,学习别人的思路,记录下来写成博客,方便自己复习。

熟能生巧!文章来源地址https://www.toymoban.com/news/detail-433599.html

到了这里,关于【C语言练习——合并两个有序序列】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言每日一题:6.移除元素+合并两个有序数组。

    一:暴力查找的方法: 1.找到对应val值的下标,返回数组的下标。 2.删除对应的下标,从前向后用后面覆盖前面。当后一个是数组最后一个数值是就赋值结束了(注意数组越界的问题)。 3.删除了一个数之后数组元素个数要–。 4.查找和删除是在一个循环里面因为val的值可能

    2024年02月15日
    浏览(46)
  • C语言 | Leetcode C语言题解之第21题合并两个有序链表

    题目: 题解:

    2024年04月12日
    浏览(39)
  • C语言实现两个集合合并及有序集合的并集(顺序存储、链式存储)

    1、两个集合并集问题 获取LA、LB的表长m、n。 从LB中第一个数据元素开始,循环n次执行:从LB中查找第i(1≤i≤n)个数据元素赋值给e;然后在LA中查找元素e,如果不存在,则将e插入在表LA的最后。 2、算法描述 3、顺序存储实现 4、链式存储实现

    2024年02月07日
    浏览(56)
  • 合并两个有序数组(简单)

    给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2 ,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意: 最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况

    2024年01月18日
    浏览(43)
  • 21. 合并两个有序链表

     

    2024年02月12日
    浏览(33)
  • 合并两个有序链表

    题目链接 :力扣21,合并两个有序链表 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 首先我们能够想到的就是 遍历一遍数组,判断两个结点的大小,将数值小的结点放在前面,数值大的不断尾插在后面 。是不是听

    2023年04月27日
    浏览(45)
  • 21.合并两个有序链表

    一、思路 二、源码 创建一个新链表 两个链表比较,小于等于取下来尾插 循环结束条件为任意一个链表为空 最后将之剩下的链表直接尾插

    2024年01月23日
    浏览(45)
  • 力扣21. 合并两个有序链表

    题目 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。  链接:21. 合并两个有序链表 - 力扣(LeetCode) 题解 设置两个指针head和tail,head用来指向新链表的头结点,tail用来进行新链表的尾插。比较两个链表,取较小的结

    2024年02月16日
    浏览(72)
  • Leetcode. 88合并两个有序数组

    合并两个有序数组 核心思路: 依次比较,取较小值放入新数组中 i 遍历nums1 , j 遍历nums2 ,取较小值放入nums3中 那如果nums[i] 和nums[j]中相等,随便放一个到nums3 那如果nums[i] 和nums[j]中相等,随便放一个到nums3 此时 nums1 中的元素已经走完了,那么直接把 nums2 中剩下的元素拿到

    2023年04月08日
    浏览(98)
  • LeetCode 0088. 合并两个有序数组

    力扣题目链接:https://leetcode.cn/problems/merge-sorted-array/ 给你两个按 非递减顺序 排列的整数数组  nums1 和 nums2 ,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。 注意: 最终,合并后数组不应由

    2024年02月13日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包