王道复试C语言第二章排序和查找——代码笔记分享

排序题

3.1C++自带库函数

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>//使用C++自带的sort函数
using namespace std;

/*
题目描述:
    对输入的n个数进行排序并输出。
输入描述:
    输入的第一行包括一个整数n(1<=n<=100)。接下来的一行包括n个整数。
输出描述:
    可能有多组测试数据,对于每组数据,将排序后的n个整数输出,每个数后面都有一个空格。每组测试数据的结果占一行。
 */

int main() {
    int n;
    int arr[101];
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    sort(arr, arr + n);//排序sort(begin,end);默认是升序,begin指向第一个元素,end指向最后一个元素的后一个元素(左闭右开)
    /*
    C语言数组:
    int arr[6]:定义包含6个元素的数组
    arr[0]...arr[5]:元素
    arr:0号元素的地址
    arr+i:i号元素的地址
    */
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>
using namespace std;

bool comp(int lhs, int rhs) {//定义降序排序
	//不发生交换的条件下返回真
	if (lhs > rhs)
		return true;
	else
		return false;
}

int main() {
	int arr[8];
	for (int i = 0; i < 8; i++) {
		scanf("%d", &arr[i]);
	}
	sort(arr, arr + 8, comp);//comp定义排序的规则,其为函数指针不需要加括号
	for (int i = 0; i < 8; i++) {
		printf("%d ", arr[i]);
	}
}

3.2整数奇偶排序

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>
using namespace std;

/*
输入10个整数,彼此以空格分隔,重新排序以后输出(也按空格分隔)。
要求:
1.先输出其中的奇数,并按从大到小排列; 
2.然后输出其中的偶数,并按从小到大排列。
*/
bool comp(int lhs, int rhs) {//不发生交换的条件下返回真
	//本题共三种情况:1.左奇右偶2.左奇大右奇小3.左偶小右偶大
	if (lhs % 2 == 1 && rhs % 2 == 0) {
		return true;
	}
	else if (lhs % 2 == 1 && rhs % 2 == 1 && lhs > rhs) {
		return true;
	}
	else if (lhs % 2 == 0 && rhs % 2 == 0 && lhs < rhs) {
		return true;
	}
	else
		return false;
}

int main() {
	int arr[10];
	for (int i = 0; i < 10; i++) {
		scanf("%d", &arr[i]);
	}
	sort(arr, arr + 10, comp);//comp定义排序的规则,其为函数指针不需要加括号
	for (int i = 0; i < 10; i++) {
		printf("%d ", arr[i]);
	}
}

3.2成绩排序

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>
using namespace std;

/*
例题3.2成绩排序 (清华大学复试上机题)
题目描述:
用一维数组存储学号和成绩,然后技成绩排序输出。
输入:
输入的第一行中包括一个整数N(1<=N<=100),它代表学生的个数。
接下来的N行中,每行包括两个整数p和q,分别代表每个学生的学号和成绩。
输出:
按照学生的成绩从小到大进行排序,并将排序后的学生信息打印出来。
如果学生的成绩相同,那么按照学号的大小从小到大排序。
*/

struct Student {//结构体
	int num;
	int grade;
};

bool comp(Student lhs, Student rhs) {
	//不发生交换的情况
	if (lhs.grade < rhs.grade) {//成绩从小到大
		return true;
	}
	else if (lhs.grade == rhs.grade && lhs.num < rhs.num) {//成绩相同,则按照学号的大小进行从小到大排序。
		return true;
	}
	else {
		return false;
	}
}

int main() {
	Student arr[101];
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d %d", &arr[i].num, &arr[i].grade);
	}
	sort(arr, arr + n, comp);
	for (int i = 0; i < n; i++) {
		printf("%d %d\n", arr[i].num, arr[i].grade);
	}
}

3.3成绩排序2

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>
using namespace std;

/*
描述题目:
输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩都按先录入排列在前的规则处理。
输入描述:
注意一个case里面有多组样例,请用循环处理输入多行,先输入要排序的人的个数,然后输入排序方法0(降序)或者1(升序)再分别输入他们的名字和成绩,以一个空格隔开。
输出描述:
按照指定方式输出名字和成绩,名字和成绩之间以一个空格隔开
*/

struct Student {//结构体
	char name[100];
	int score;
	int id;
};

bool comp1(Student lhs, Student rhs) {
	//降序排列,不发生交换的情况
	if (lhs.score > rhs.score) {//成绩从大到小
		return true;
	}
	else if (lhs.score == rhs.score && lhs.id < rhs.id) {
		return true;
	}
	else {
		return false;
	}
}


bool comp2(Student lhs, Student rhs) {
	//升序排列,不发生交换的情况
	if (lhs.score < rhs.score) {//成绩从小到大
		return true;
	}
		else if (lhs.score == rhs.score && lhs.id < rhs.id) {
		return true;
	}
	else {
		return false;
	}
}

int main() {
	Student arr[1000];
	int n, kind;
	while (scanf("%d %d", &n, &kind) != EOF) {
		for (int i = 0; i < n; i++) {
			scanf("%s %d", &arr[i].name, &arr[i].score);
			arr[i].id = i;
		}
		if (kind == 0) {
			sort(arr, arr + n, comp1);
		}
		else {
			sort(arr, arr + n, comp2);
		}
		for (int i = 0; i < n; i++) {
			printf("%s %d\n", arr[i].name, arr[i].score);
		}
	}
}

查找题

3.4找x

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
/*
描述:
输入一个数n,然后输入n个数值各不相同,再输入一个值x,输出这个值在这个数组中的下标(从0开始,若不在数组中则输出-1)。
输入:
测试数据有多组,输入n(1<=n<=200),接着输入n个数,然后输入x。
输出:
对于每组输入,请输出结果。
*/
int main() {
	int num, arr[201], index;
	scanf("%d", &num);
	for (int i = 0; i < num; i++) {
		scanf("%d", &arr[i]);
	}
	scanf("%d", &index);
	for (int j = 0; j < num; j++) {//顺序查找(效率低)
		if (arr[j] == index) {
			printf("%d", j);
			return 0;
		}
	}
	printf("-1");
	return 0;
}

3.5多次查找

方法一:二分查找

牛客网OJ

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <algorithm>
using namespace std;

/*
题目:
m次查找长度为n的数组元素,判断元素是否存在。
输入:
输入待查数组总个数n,输入待查数组arr,输入要查询的总次数m,输入要查询的数字x
输出:
根据次数m,输出相应次数的结果true/false
*/

int arr[100];//定义全局数组
bool binarySearch(int n, int x) {
	int left = 0;
	int right = n - 1;
	while (left <= right) {//牢记是<=(最后的边界情况left和right相等,下次right可能会变成left-1)
		int mid = (left + right) / 2;
		if (arr[mid] == x) {
			return true;
		}
		else if (arr[mid] > x) {
			right = mid - 1;
		}
		else {
			left = mid + 1;
		}
	}
	return false;
}

int main() {
	int n, m;
	scanf("%d", &n);//输入待查数组总个数
	for (int i = 0; i < n; i++) {
		scanf("%d", &arr[i]);//输入待查数组
	}
	sort(arr, arr + n);//排序
	scanf("%d", &m);//输入要查询的总次数
	for (int i = 0; i < m; i++) {
		int x;
		scanf("%d", &x);//输入要查询的数字
		if (binarySearch(n, x)) {
			printf("YES\n");
		}
		else {
			printf("NO\n");
		}
	}
}

方法二:map

map的底层是一个二叉搜索树。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
#include<map>
using namespace std;

/*
题目:
m次查找长度为n的数组元素,判断元素是否存在。
输入:
输入待查数组总个数n,输入待查数组arr,输入要查询的总次数m,输入要查询的数字x
输出:
根据次数m,输出相应次数的结果true/false
*/

int main() {
	int n, m;
	int arr[101];
	map<int, int> findIndex;
	scanf("%d", &n);//输入待查数组总个数
	for (int i = 0; i < n; i++) {
		scanf("%d", &arr[i]);//输入待查数组
		findIndex[arr[i]] = i;//将数组的元素作为键,数组元素的下标作为值,插入到map当中
	}
	scanf("%d", &m);//输入要查询的总次数
	for (int i = 0; i < m; i++) {
		int x;
		scanf("%d", &x);//输入要查询的元素
		/*
		map.find():会返回找到的那个元素的迭代器
		map.begin():指向容器中第一个元素
		map.end():指向容器中最后一个元素的后一个元素(即为空元素)
		*/
		if (findIndex.find(x) == findIndex.end()) {
			printf("NO\n");
		}
		else {
			printf("YES\n");
		}
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值