数据排序算法

1.选择排序

基本思想:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在待排序的数列的最前面,直到全部待排序列的数据排完

#include<bits/stdc++.h>
using namespace std;
int main() {
	int i, j, k, n;
	double a[10001], temp;
	cin >> n;
	for ( i = 1; i <= n; i++) {
		cin >> a[i];;
	}
	for (i = 1; i <= n; i++) {
		k = i;
		for (j = i + 1; j <= n; j++) {
			if (a[j] < a[k]) {
				k = j;
			}}
			if (k != i) {
				temp = a[i]; a[i] = a[k]; a[k] = temp;
			}
		
	}
	for ( i = 1; i <= n; i++) {
		cout << a[i] << " ";
	}

	return 0;
}

2.冒泡排序

每轮将n个数据的排序规模转化成n-1,每两两间比较

改进:对于有些数据,并不一定需要排那么多次数,可以设置一个布尔类型的数据作为判断标志

#include<bits/stdc++.h>
using namespace std;
const int MAX = 10001;
bool flag;
int main() {
	int n, i, j;
	double a[MAX],temp;
	cin >> n;
	for (i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for ( i = 1; i <= n-1; i++) {
        flag = true;
		for (j = 1; j <= n - i; j++) {
			if (a[j] > a[j + 1]) {
				temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
                flag = false;
			}
		}
        if(flag){
            break;
	}
	for (int i = 1; i <= n; i++) {a
		cout << a[i] << " ";
	}

	return 0;
}

车厢重组问题: 有两行数据,第一行是车厢总数N(不大于10000),第二行是N个不同的数表示初始的车厢顺序。输出最少旋转次数

#include<bits/stdc++.h>
using namespace std;
int main() {
	int i, j, k, n,count =0;
	double a[10001], temp;
	bool flag ;
	cin >> n;
	for ( i = 1; i <= n; i++) {
		cin >> a[i];;
	}
	for (i = 1; i <= n-1; i++) {
		flag = true;
		for (j = 1; j <= n - i; j++) {
			if (a[j] > a[j + 1]) {
				swap(a[j], a[j + 1]);
				count++;
				flag = false;
			}
			if (flag) {
				break;
			}
		}
	}
	cout << count << endl;
	return 0;
}

插入排序

当读入一个数据时,在已排序好的序列中,搜寻它正确的位置,再放入读入读入的元素。但不该忽略一个重要的问题:在插入这个元素前,应当先将它后面的所有元素后移一位,以保证插入位置的原元素不被覆盖

#include<bits/stdc++.h>
using namespace std;
int main() {
	int  len;
	double a[101];
	cin >> len;
	for (int i = 1; i <= len; i++) {
		cin >> a[i];
	}
		for (int j = 1; j <= len; j++)
		{
			int key = a[j];
			int i = j - 1;
			while (i >= 0 && a[i] > key)
			{
				a[i + 1] = a[i];
				i--;
			}
			a[i + 1] = key;
		}
		for (int i = 1; i <= len; i++) {
			cout << a[i] << " ";
		}
	return 0;
}

桶排序

若待排序的值在一个明显有限范围内时,可设计有限个有序桶,待排序的值装入对应的桶,桶号就是待排序的值,顺序输出各桶内的值,将得到有序的序列

#include<bits/stdc++.h>
using namespace std;
int a[1001], b[1001];
int main() {
	int k;
	cin >> k;
	for (int i = 1; i <= k; i++) {
		cin >> a[i];
		b[a[i]]++;
	}
	for (int i = 1; i <= 1001; i++) {
		while (b[i] > 0) {
			cout << i << " ";
			b[i]--;
		}
	}

	return 0;
}

明明的随机数:有2行,第1行为1个正整数,表示所生成的随机数个数:N; 第2行有N个用空格隔开的正整数,为所产生的随机数。

#include<bits/stdc++.h>
using namespace std;
int  b[1001];
int main() {
	int k,t,count=0;
	cin >> k;
	for (int i = 1; i <= k; i++) {
		cin >> t;
		if (b[t]==0) {
			b[t]++;
			count++;
		}
	}
	cout << count << endl;
	for (int i = 1; i <= 1001; i++) {
		if (b[i] != 0) {
			cout << i << " ";
		}
	}

	return 0;
}

快速排序:是对冒泡排序的一种改进

基本思想:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键词小,则可分别对这两部分记录继续进行排序,以达到整个序列有序

#include<bits/stdc++.h>
using namespace std;
int get_mid(int b[], int left, int right) {
	int pivot = b[left];
	while (left < right) {
		while (b[right] >= pivot && left < right) 
		{	right--;}
		b[left] = b[right];
		while (b[left] <= pivot && left < right) 
		{left++;}
		b[right] = b[left];
	b[left] = pivot;
	}
	return left;
}
void quick_sort(int b[], int left, int right) {
	if (left < right) {
		int mid = get_mid(b, left, right);
		quick_sort(b, left, mid - 1);
		quick_sort(b, mid + 1, right);
	}
}
int main() {
	int c[10] = { 6,3,17,9,8,7,5,12,23,11 };
	quick_sort(c, 0, 9);
	for (int i = 0; i < 10; i++) {
		cout << c[i] << " ";
	}
	return 0;
}

int finding(int l,int r,int k)
{
    if(l==r) return a[l];
    int i=l,j=r;
    int mid=(l+r)>>1;
    int x=a[mid];
    while(i<=j)
    {
        while(a[j]>x) j--;
        while(a[i]<x) i++;
        if(i<=j)
        {
            swap(a[i],a[j]);
            i++,j--;
        }
    }
    if(k<=j) return finding(l,j,k);
    else if(k>=i) return finding(i,r,k);
    else return a[k];
}

inline int read()
{
    int x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = (x<<1) + (x<<3) + (ch^48);
        ch = getchar();
    }
    return x * f;
}

归并排序:建立在归并操作的一种有效算法,该算法是采用分治算法的典型应用

#include<bits/stdc++.h>
using namespace std;
int a[1001], c[1001];
void msort(int left, int right) {
	if (left == right) { return; }
	int mid = (left + right) / 2;
	int  i = left, j = mid + 1, k = left;
	msort(left, mid);
	msort(mid + 1, right);
	while (i <= mid && j <= right) {
		if (a[i] <= a[j]) {
			c[k] = a[i]; k++; i++;
		}
		else {
			c[k] = a[j]; k++; j++;
		}
	}
	while (i <= mid) {
		c[k] = a[i]; k++; i++;
	}
	while (j <= right) {
		c[k] = a[j]; k++; j++;
	}
	for (int i = left; i <= right; i++) {
		a[i] = c[i];
	}
}
int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	msort(1, n);
	for (int i = 1; i <= n; i++) {
		cout << a[i] << " ";
	}
	return 0;
}

逆序对问题:对与给定的叔祖数列,求其逆序对数量(主要归并排序)

#include<bits/stdc++.h>
using namespace std;
int a[5] = { 3,1,4,5,2 };
int c[5], ans;
void msort(int left, int right) {
	if (left == right) { return; }
		int mid = (left + right) / 2;
		int i = left; int j = mid + 1, k = left;
		msort(left, mid);
		msort(mid+1, right);
		while(i <= mid && j <= right) {
			if (a[i] <= a[j]) {
				c[k] = a[i]; k++; i++;
			}
			else {
				c[k] = a[j]; k++;j++;
				ans += mid - i + 1;
				cout << endl;
				cout << ans << endl;
			}
		}
		while (i <= mid) {
			c[k] = a[i]; k++; i++;
		}
		while (j <= right) {
			c[k] = a[j]; k++; j++;
		}
		for (int i = left; i <= right; i++) {
			a[i] = c[i];
		}

}
int main() {
	msort(0, 4);
	for (int i = 0; i <= 4; i++) {
		cout << a[i]<<" ";
	}
	cout << endl;
	cout << "共计" << ans << "对逆序对" << endl;
	return 0;
}

1.谁考了第k名

#include<bits/stdc++.h>
using namespace std;
struct student {
	int id;
	int score;
};
student a[1001];
int get_mid(student a[], int left, int right) {
	int pivot = a[left].score;
	while (left < right) {
		while (a[right].score > pivot && left < right) {
			right--;
		}
		a[left].score = a[right].score;
		while (a[left].score < pivot && left < right) {
			left++;
		}
		a[right].score = a[left].score;
		a[left].score = pivot;
	}
	return left;

}
void quick_sort(student a[],int left,int right) {
	if (left < right) {
		int mid = get_mid(a, left, right);
		quick_sort(a, left, mid);;
		quick_sort(a, mid + 1, right);
	}
}
int main() {
	int n, k;
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].id>> a[i].score;
	}
	quick_sort(a, 1, n);
	cout << a[k].id << " " << a[k].score;

	return 0;
}

2.奇数单增数列

#include<bits/stdc++.h>
using namespace std;
int a[10001];
int get_mid(int a[], int left, int right) {
	int pivot = a[left];
	while (left < right) {
		while (a[right] >= pivot && left < right) {
			right--;
		}
		a[left] = a[right];
		while (a[left] <= pivot && left < right) {
			left++;
		}
		a[right] = a[left];
		a[left] = pivot;
	}
	return left;
}
void quick_sort(int a[], int left, int right) {
	if (left < right) {
		int mid = get_mid(a, left, right);
		quick_sort(a, left, mid);
		quick_sort(a, mid + 1, right);
	}

}
int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	quick_sort(a, 1, n);
	for (int i = 1; i <= n; i++) {
		if(a[i]/2!=0){
			cout << a[i] << " ";
		}
	}
		return 0;
}

3.*成绩排序,分数相同则字典序小在前

return a.score > b.score || a.score == a.score && strcmp(a.name, b.name) < 0;作为字典序和数值判断函数

#include<bits/stdc++.h>
using namespace std;
int n;
struct stu {
	int score;
	char name[20];
};
stu a[1001];
bool is_prior(stu &a,stu &b) {
	return a.score > b.score || a.score == a.score && strcmp(a.name, b.name) < 0;
	//成绩和字典序判断
}
void bubble_sort(stu a[]) {
	for (int i = 1; i <= n - 1; i++) {
		for (int j = 1; j <= n - i; j++) {
			if (is_prior(a[j+1],a[j])) {
				swap(a[j+1],a[j]);
			}
		}
	}

}
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].name>>a[i].score;
	}
	bubble_sort(a);
	for (int i = 1; i <= n; i++) {
		cout << a[i].name << " " << a[i].score << endl;;
	}
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct Stu
{
    char name[25];
    int score;
};
bool isPrior(Stu &a, Stu &b)//a是否应该排在b的前面 
{
    return a.score > b.score || a.score == b.score && strcmp(a.name, b.name) < 0;
}
int main()
{
    Stu stu[25];
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++i)
		cin >> stu[i].name >> stu[i].score;
	for(int i = 1; i <= n-1; ++i)//冒泡排序 
	   for(int j = 1; j <= n-i; ++j)
	       if(isPrior(stu[j+1], stu[j]))//如果stu[j+1]应该在stu[j]前面
                swap(stu[j], stu[j+1]); 
    for(int i = 1; i <= n; ++i)
		cout << stu[i].name << ' ' << stu[i].score << endl;
	return 0;
}

4.奖学金Noip2007

题目描述

某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。期末,每个学生都有3门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的。

任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名学生的学号和总分。注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:

包含n+1行:

第1行为一个正整数n(小于300),表示该校参加评选的学生人数。

第2到n+1行,每行有3个用空格隔开的数字,每个数字都在0到100之间。第j行的3个数字依次表示学号为 j−1 的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为1∼n (恰好是输入数据的行号减1)。

共有5行,每行是两个用空格隔开的正整数,依次表示前5名学生的学号和总分。

#include<bits/stdc++.h>
using namespace std;
int n;
struct stu {
	int id;
	int yuwen, shuxue, yingyu;
	int sum = yuwen + shuxue + yingyu;
};
stu a[100];
bool is_prior(stu &p,stu &q) {
	if (p.sum > q.sum) {
		return true;
	}
	if (p.sum == q.sum && p.yuwen > q.yuwen) {
		return true;
	}
	if (p.sum == q.sum && p.yuwen == q.yuwen && p.id < q.id) {
		return true;
	}
	return false;
}
int main() {
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i].yuwen >> a[i].shuxue >> a[i].yingyu;
		a[i].id = i;
		a[i].sum = a[i].shuxue + a[i].yingyu + a[i].yuwen;
	}
 for (int i = 1; i <= n - 1; i++) {
		for (int j = 1; j <= n - i; j++) {
			if (is_prior(a[j + 1], a[j])) {
				swap(a[j + 1], a[j]);
			}
		}
	}
	for (int i = 1; i <= 5; i++) {
		cout << a[i].id << " " << a[i].sum<<endl;
	}

	return 0;
}

5.整数奇偶排列

#include<bits/stdc++.h>
using namespace std;;
int a[11], b[10], c[10];
int indexb, indexc;
void sort(int a[]) {
	for (int i = 1; i <= 10; i++) {
		if (a[i] % 2 != 0) {
			indexb++;
			b[indexb] = a[i];
		}
		else {
			indexc++;
			c[indexc] = a[i];
		}
	}
}
int main() {
	for (int i = 1; i <= 10; i++) {
		cin >> a[i];
	}
	sort(a);
	for (int i = 1; i <= indexb - 1;i++) {
		for (int j = 1; j <=indexb - i; j++) {
			if (b[j] < b[j + 1]) {
				swap(b[j], b[j + 1]);
			}
		}
	}
	for (int i = 1; i <= indexc-1; i++) {
		for (int j = 1; j <= indexc - i; j++) {
			if (c[j] > c[j + 1]) {
				swap(c[j + 1], c[j]);
			}
		}
	}
	for (int i = 1; i <= indexb; i++) {
		cout << b[i] << " ";
	}
	for (int i = 1; i <= indexc; i++) {
		cout << c[i] << " ";
	}
	
	return 0;
}

6.单词排序

while (cin >> w[n].word) {

n++;

}

n--;//最后一次输入的值是EOF,不是有效的值,n应该减1

使用此方法不断录入字符串 ctrl-+z+回车结束

#include<bits/stdc++.h>
using namespace std;
int n;
struct Word {
	char word[50];
};
Word w[101];
bool is_prior(Word &a,Word &b) {
	return strcmp(a.word, b.word) < 0;
}
int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> w[i].word;
	}
	for (int i = 1; i <= n - 1; i++) {
		for (int j = 1; j <= n - i; j++) {
			if (is_prior(w[j + 1], w[j])) {
				swap(w[j + 1], w[j]);
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (strcmp(w[i].word, w[i+1].word) == 0) {
			i++;
		}
		else {
			cout << w[i].word << endl;
		}

	}
	return 0;
}
#include<bits/stdc++.h>
using namespace std;

struct Word {
	char word[50];
};
Word w[101];
bool is_prior(Word &a,Word &b) {
	return strcmp(a.word, b.word) < 0;
}
int main() {
	int n = 1;
	while (cin >> w[n].word) {
		n++;
	}
	n--;//最后一次输入的值是EOF,不是有效的值,n应该减1 
	
	for (int i = 1; i <= n - 1; i++) {
		for (int j = 1; j <= n - i; j++) {
			if (is_prior(w[j + 1], w[j])) {
				swap(w[j + 1], w[j]);
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		if (strcmp(w[i].word, w[i+1].word) == 0) {
			i++;
		}
		else {
			cout << w[i].word << endl;
		}

	}
	return 0;
}

7.统计字符数

描述

给定一个由a-z这26个字符组成的字符串,统计其中哪个字符出现的次数最多。

【输入】

输入包含一行,一个字符串,长度不超过1000。

【输出】

输出一行,包括出现次数最多的字符和该字符出现的次数,中间以一个空格分开。如果有多个字符出现的次数相同且最多,那么输出ascii码最小的那一个字符。

#include<bits/stdc++.h>
using namespace std;
int main() {
	char st[128];
	int cs[128] = {0};
	cin >> st;
	int len = strlen(st);
	int max = 0;
	for (int i = 0; i < len; i++) {
		cs[st[i]]++;
	}
	for (int i = 0; i < 128; i++) {
		if (cs[i] >cs[max]) {
			max = i;
		}
	}
	cout << char(max) << " " << cs[max];
	return 0;
}
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cr不是铬

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值