C语言练习-day19

题目:一个长度为L(L>=1)的升序序列R,处在第L/2个位置的数称为R的中位数。例如,若序列R1 = {11,13,15,17,19},则R1的中位数是15,两个序列的中位数是含它们所有元素的升序序列的中位数。例如R2 = {2,4,6,8,20},则R1和R2的中位数是11.现在有两个升序序列(不一定等长),找出两个序列L1和L2的中位数。

输入:两个顺序表,各表长length,以及表中各元素的值,类型为int。

输出:两个序列的中位数。

优化目标:无

算法思想:首先计算出中位数的位置,然后在L1和L2中去依次比较,k记录是否到达中位数,key记录中位数,L1和L2谁小就往后移,k++,如果L1和L2某一个顺序表都比较完了还没找到中位数,则就在现在还没遍历完的顺序表中找,当k等于中位数位置就找到了,然后返回key。



#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

//查找中位数
int M_Search(SqList L1,SqList L2){

	int mid,length = (L1.length + L2.length)/2,flag = 0;
	if((L1.length + L2.length)%2 == 0){
		mid = length;
	}
	else{
		mid = length+1;
	}
	
	int i = 1,j = 1,k = 1,key;
	while(i<=L1.length&&j<=L2.length){
		if(L1.R[i].key>L2.R[j].key){
			if(k == (mid)){
				key = L2.R[j].key;
				flag =1;
				break;
			}
			j++;k++;
		}
		else{
			if(k == (mid)){
				key = L1.R[i].key;
				flag = 1;
				break;
			}
			i++;k++;
		}
	}
	if(flag == 0){
		if(i<=L1.length){
			while(1){
				if(k == mid){
					key = L1.R[i].key;
					break;
				}
				i++;k++;
			}
		}
		else if(j<=L1.length){
			while(1){
				if(k == mid){
					key = L2.R[j].key;
					break;
				}
				j++;k++;
			}
		}
	}
	
	
	return key;
}


//顺序表初始化
void ListInit(SqList &L){
	int i,length,key;
	printf("请输入顺序表的长度(小于20):");	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}

//输出顺序表
void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L1,L2;
	
	ListInit(L1);
	PrintList(L1);
	
	ListInit(L2);
	PrintList(L2);
		
	int key =  M_Search(L1,L2);

	printf("L1和L2的中位数是:%d",key);
	
	return 0;
}

题目:已知一个整数序列L = {a1,a2,..,a(n)},其中1<=ai<=n(1<=i<=n)。若存在a(p1)=a(p2)=...=a(pm)=x且m>n/2(1<=a(pk)<=n,1<=k<=n),则称x为A的主元素。如A = {0,5,5,3,5,7,5,5},则5为主元素;又如A = {0,5,5,3,5,1,5,7},则A中没有主元素。请设计一个算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。

输入:表长length,以及表中各元素的值,类型为int。

输出:顺序表的主元素。

优化目标:第一个方式牺牲空间和时间的方法做出来的,第二个就是空间时间复杂度都很低,思想很好,可以学习。

方法一:算法思想:首先创建一个顺序表,顺序表的长度为输入的顺序表的长度,并初始化每个值为0,接下来依次遍历输入的顺序表,将每次遍历到的值,在对应自创建的顺序表的序号的值处加一,然后去遍历创建的顺序表,如果有一个值大于n/2的话说明该值就是主元素,否则没找到主元素。

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE+1];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

//查找主元素
int Majority(SqList L){
	SqList LP;
	LP.length = L.length;
	for(int i=1;i<=LP.length;i++){
		LP.R[i].key = 0;
	}
	for(int i=1;i<=L.length;i++){
		LP.R[L.R[i].key].key++;
	}
	for(int i=1;i<=LP.length;i++){
		if(LP.R[i].key>(LP.length/2)){
			return i;
		}
		
	}
	return -1;
	
	
}

//顺序表初始化
void ListInit(SqList &L){
	int i,length,key;	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	printf("请输入顺序表的长度(小于20):");

	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}

//输出顺序表
void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	PrintList(L);
	int k = Majority(L);
	if(k!=-1){
		printf("主元素为:%d\n",k);
	}
	else{
		printf("该顺序表没有主元素");
	}
	
	return 0;
}

方法二:算法思想:从前向后扫描数组元素,标记出可能成为主元素k,然后重新计数,确认k是否为主元素。

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE+1];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;


//查找主元素
int Majority(SqList L){
	int i,k = 1,key = L.R[0].key;
	for(i = 2;i<=L.length;i++){
		if(L.R[i].key == key){
			k++;
		}
		else{
			if(k > 0){
				k--;
			}
			else{
				key = L.R[i].key;
				k=1;
			}
		}
	}
	
	if(k>0){
		k = 0;
		for(i = 1;i<=L.length;i++){
			if(key == L.R[i].key){
				k++;
			}
		}
	}
	
	if(k > (L.length/2)){
		return key;
	}
	return -1;
	
	
}

//顺序表初始化
void ListInit(SqList &L){
	int i,length,key;	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	printf("请输入顺序表的长度(小于20):");

	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}

//输出顺序表
void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	PrintList(L);
	int k = Majority(L);
	if(k!=-1){
		printf("主元素为:%d\n",k);
	}
	else{
		printf("该顺序表没有主元素");
	}
	
	return 0;
}

题目:给定一个含n个整数的数组,请设计一个算法,找出数组中未出现的最小正整数。例如数组{-5,3,2,3}中未出现的最小正整数是1;数组{1,2,3}未出现的最小正整数是4。

输入:表长length,以及表中各元素的值,类型为int。

输出:顺序表中未出现的最小正整数。

优化目标:无。

算法思想:创建一个长度为输入顺序表长度一样大的顺序表,初始化所有值为0,用于记录在输入顺序表中是否出现了1~n中的正整数。当输入顺序表中出现小于等于0或大于n的元素,就说明1~n中出空余位置,返回结果必然出现在1~n之间,因此对小于等于0或大于n的元素不做操作。

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE+1];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

//查找未出现的最小正整数
int findMissMin(SqList &L){
	SqList L1;
	L1.length = L.length;
	for(int i=1;i<=L1.length;i++){
		L1.R[i].key = 0;
	}
	
	for(int i=1;i<=L.length;i++){
		if((L.R[i].key>0)&&(L.R[i].key<=L.length)){
			L1.R[L.R[i].key].key=1;
		}
	}
	for(int i=1;i<=L1.length;i++){
		if(L1.R[i].key==0){
			return i;
		}
	}
	
	return L.length+1;
	
	
}

//顺序表初始化
void ListInit(SqList &L){
	int i,length,key;	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	printf("请输入顺序表的长度(小于20):");

	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}

//输出顺序表
void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L;
	ListInit(L);
	PrintList(L);
	int k = findMissMin(L);
	printf("未出现的最小正整数元素为:%d\n",k);
	PrintList(L);
	
	return 0;
}

题目:定义三元组(a,b,c)(a、b、c均为正数)的距离D = |a-b|+|b-c|+|c-a|。给定3个非空整数集合L1,L2,L3,按升序分别存储在3个数组中。请设计一个算法,计算并输出所有可能的三元组(a,b,c)(a属于L1,b属于L2,c属于L3 )中的最小距离。例如L1 = {-1,0,9},L2 = {-25,-10,10,11},L3 = {2,9,17,30,41},则最小的距离为2.相应的三元组为(9,10,9)。

输入:三个顺序表,各表长length,以及表中各元素的值,类型为int。

输出:顺序表中未出现的最小正整数。

优化目标:无。

算法思想:以糖果为例,我们需要平衡三栏糖果中的数量,使差距最小,三栏中谁最少就换谁,依次比较之间的差距,如果比当前记录的最小的值还小就替换最小值。

#include<stdio.h>
#include<stdlib.h>

#define MAXSIZE 20

#define MAX 999

typedef struct{
	int key;  //关键字
}KeyType;

typedef struct{
	KeyType R[MAXSIZE+1];   //R[0]闲置
	int length;   //顺序表的长度
}SqList;

int abs_(int a){
	if(a<0){
		return -a;
	}
	return a;
}

int min_(int a,int b,int c){
	if(a<=b&&a<=c){
		return 1;
	}
	return 0;
}

//在最小距离D
int findMinofTrip(SqList L1,SqList L2,SqList L3){
	int i = 1,j = 1,k = 1,D_min = MAX;
	while(i<=L1.length&&j<=L2.length&&k<=L3.length&&D_min>0){
		int D = abs_(L1.R[i].key-L2.R[j].key)+abs_(L1.R[i].key-L3.R[k].key)+abs_(L3.R[k].key-L2.R[j].key);
		if(D<D_min){
			D_min = D;
		}
		if(min_(L1.R[i].key,L2.R[j].key,L3.R[k].key)){
			i++;
		}
		else if(min_(L2.R[j].key,L3.R[k].key,L1.R[i].key)){
			j++;
		}
		else{
			k++;
		}
	}
	return D_min;	
	
}

//顺序表初始化
void ListInit(SqList &L){
	int i,length,key;	
	for(i = 1;i<=MAXSIZE;i++){
		L.R[i].key = 0;
	}
	
	printf("请输入顺序表的长度(小于20):");

	scanf("%d",&length);
	L.length = length;
	for(i = 1;i<=length;i++){
		printf("请输入第%d个元素:",i);
		scanf("%d",&key);
		L.R[i].key = key;
	}
}

//输出顺序表
void PrintList(SqList L){
	int i;
	printf("顺序表内容是:");
	for(i = 1;i<=L.length;i++){

		printf("%d  ",L.R[i].key);
	}
	printf("\n");
}


int main(){
	SqList L1,L2,L3;
	ListInit(L1);
	PrintList(L1);
	
	ListInit(L2);
	PrintList(L2);
	
	ListInit(L3);
	PrintList(L3);
	
	int k = findMinofTrip(L1,L2,L3);
	printf("最小距离为:%d\n",k);
	
	return 0;
}

今天主要是做了顺序表的4个题,我觉得最后的一个算法是印象最深,让我联想到我们给三个桶加水,让他们尽可能高度一致,每次加最少的一个,以使差距最小。明天就要练习链表的题。

C语言学习计划(60天) 第一周(7天) - Day 1:学习C语言基本概念和语法规则 - Day 2:学习C语言数据类型和变量 - Day 3:学习C语言运算符和表达式 - Day 4:学习C语言控制结构之if语句 - Day 5:学习C语言控制结构之switch语句 - Day 6:学习C语言循环结构之while语句 - Day 7:学习C语言循环结构之for语句 第二周(7天) - Day 8:学习C语言函数 - Day 9:学习C语言指针 - Day 10:学习C语言数组 - Day 11:学习C语言字符串 - Day 12:学习C语言结构体 - Day 13:学习C语言文件操作 - Day 14:练习使用C语言开发简单的控制台程序 第三周(7天) - Day 15:学习C语言内存管理 - Day 16:学习C语言动态内存分配 - Day 17:学习C语言预处理器 - Day 18:学习C语言定义 - Day 19:学习C语言枚举 - Day 20:学习C语言位运算 - Day 21:练习使用C语言开发简单的应用程序 第四周(7天) - Day 22:学习C语言递归 - Day 23:学习C语言排序算法 - Day 24:学习C语言查找算法 - Day 25:学习C语言数据结构之链表 - Day 26:学习C语言数据结构之栈和队列 - Day 27:学习C语言数据结构之树 - Day 28:练习使用C语言开发简单的数据结构应用程序 第五周(7天) - Day 29:学习C语言多线程编程 - Day 30:学习C语言网络编程 - Day 31:学习C语言图像处理 - Day 32:学习C语言音频处理 - Day 33:学习C语言视频处理 - Day 34:学习C语言游戏开发 - Day 35:练习使用C语言开发简单的图像、音频、视频处理程序和游戏 第六周(7天) - Day 36:学习C语言算法优化 - Day 37:学习C语言代码调试与测试 - Day 38:学习C语言代码规范和文档 - Day 39:学习C语言代码版本管理 - Day 40:学习C语言代码安全和防护 - Day 41:学习C语言代码性能优化 - Day 42:练习使用C语言开发高质量、高效率、高安全性、高可维护性、高可读性的程序 第七周(7天) - Day 43:学习C语言面向对象编程 - Day 44:学习C语言泛型编程 - Day 45:学习C语言函数式编程 - Day 46:学习C语言元编程 - Day 47:学习C语言并发编程 - Day 48:学习C语言反射编程 - Day 49:练习使用C语言开发高级编程范式的程序 第八周(7天) - Day 50:学习C语言扩展库和框架 - Day 51:学习C语言开源项目和社区 - Day 52:学习C语言开发环境和工具 - Day 53:学习C语言代码优化和性能测试工具 - Day 54:学习C语言代码检查和版本管理工具 - Day 55:学习C语言图形界面开发工具和框架 - Day 56:练习使用C语言开发高质量、高性能、高可维护性、高可读性、高效率、高安全性、高可扩展性、高易用性的程序 第九周(7天) - Day 57:学习C语言嵌入式开发 - Day 58:学习C语言物联网开发 - Day 59:学习C语言人工智能开发 - Day 60:练习使用C语言开发嵌入式系统、物联网系统、人工智能系统 总结: 通过60天的学习和练习,我们可以掌握C语言的基本语法和常用技巧,熟悉C语言的开发环境和工具,了解C语言程序设计的主要思想和方法,掌握C语言高级编程范式和开发技术,达到C语言程序设计的高水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值