草庐IT

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

初学C语言者 2023-06-24 原文

合并两个有序序列


前言

第一行包含两个正整数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 显示利用数组开辟空间,再将两个数组合并后,通过冒泡排序算法进行排序:

方法1的思路见下图:

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;
}

结果见下图所示:


【初阶数据结构与算法 1】时间复杂度与空间复杂度(1)2.3.5 练习5 中,已经详细学习过冒泡算法的时间复杂度为 O(N^2)

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

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

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

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;

}

结果见下图所示:


方法2的时间复杂度为 O(m+n).

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

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

方法3的思路见下图:

//动态内存版
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语言练习——合并两个有序序列】的更多相关文章

  1. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby - 如果指定键的值在数组中相同,如何合并哈希 - 2

    我有一个这样的哈希数组:[{:foo=>2,:date=>Sat,01Sep2014},{:foo2=>2,:date=>Sat,02Sep2014},{:foo3=>3,:date=>Sat,01Sep2014},{:foo4=>4,:date=>Sat,03Sep2014},{:foo5=>5,:date=>Sat,02Sep2014}]如果:date相同,我想合并哈希值。我对上面数组的期望是:[{:foo=>2,:foo3=>3,:date=>Sat,01Sep2014},{:foo2=>2,:foo5=>5:date=>Sat,02Sep2014},{:foo4=>4,:dat

  4. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  5. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

  6. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  7. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  8. 7个大一C语言必学的程序 / C语言经典代码大全 - 2

    嗨~大家好,这里是可莉!今天给大家带来的是7个C语言的经典基础代码~那一起往下看下去把【程序一】打印100到200之间的素数#includeintmain(){ inti; for(i=100;i 【程序二】输出乘法口诀表#includeintmain(){inti;for(i=1;i 【程序三】判断1000年---2000年之间的闰年#includeintmain(){intyear;for(year=1000;year 【程序四】给定两个整形变量的值,将两个值的内容进行交换。这里提供两种方法来进行交换,第一种为创建临时变量来进行交换,第二种是不创建临时变量而直接进行交换。1.创建临时变量来

  9. git使用常见问题(提交代码,合并冲突) - 2

    文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g

  10. 牛客网专项练习30天Pytnon篇第02天 - 2

    1.在Python3中,下列关于数学运算结果正确的是:(B)a=10b=3print(a//b)print(a%b)print(a/b)A.3,3,3.3333...B.3,1,3.3333...C.3.3333...,3.3333...,3D.3.3333...,1,3.3333...解析:    在Python中,//表示地板除(向下取整),%表示取余,/表示除(Python2向下取整返回3)2.如下程序Python2会打印多少个数:(D)k=1000whilek>1:    print(k)k=k/2A.1000 B.10C.11D.9解析:    按照题意每次循环K/2,直到K值小于等

随机推荐