问题描述:
小明来到一个景区游玩,但是他的时间有限,没办法逛遍所有的景点,所以他从网上下载了每个景点的评分,他希望能够使游览的景点的评分总和最高,于是他希望你帮他对于N个景点排下序。
输入格式:
输入的第一行包含一个正整数N,表示N个景点。
第二行有N个正整数,表示每个景点的评分值。
输出格式:
输出一行,包含N个正整数,表示N个景点的评分从大到小的排列
样例输入:
4
3 2 4 1
样例输出:
4 3 2 1
问题分析:
这个问题,其实就是一个简单的排序问题,之所以要写这个简单的题,是因为我想借着这道题把常用的排序方法:冒泡排序
,选择排序
,插入排序
,快速排序
讲一下。
算法实现:
1、冒泡排序复杂度为O(n^2)
原理
:比较相邻的元素。如果第一个比第二个大,就交换他们两个。对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
代码实现
:
static void maopao(int[] a){
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++)
{ if(a[j]<a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}}
}}
测试
:
n=9
输入:1 3 5 8 0 14 57 90 13
输出:90 57 14 13 8 5 3 1 0
2、选择排序时间复杂度为 O(N^2)
原理
:第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。
代码实现
:
static void choose(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[i] < a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}}
测试
:
n=10
输入:1 3 5 8 0 14 57 90 13 100
输出:100 90 57 14 13 8 5 3 1 0
3、插入排序时间复杂度为 O(N^2)
插入排序,一般也被称为直接插入排序。对于少量元素
的排序,它是一个有效的算法 。
执行流程
:在待排序的元素中,假设前面n-1(其中n>=2)个数已经是排好顺序的,现将第n个数插到前面已经排好的序列中,然后找到合适自己的位置,使得插入第n个数的这个序列也是排好顺序的。按照此法对所有元素进行插入,直到整个序列排为有序的过程,称为插入排序。
代码实现
:
static void insert(int[] a) {
int number;//要插入的数据
int index;// 插入位置的指针,
for (int i = 1; i < a.length; i++) {
number = a[i];
index= i - 1;
while (index >= 0 && number > a[index]) {
a[index + 1] = a[index];
index--;
}
a[index + 1] = number;
}
}
测试
:
n=4
输入:1 3 5 8
输出:8 5 3 1
4、快速排序时间复杂度为 O(N*logN)
快速排序是对冒泡排序算法的一种改进。
快速排序算法通过多次比较和交换来实现排序,其排序流程
如下:
(1)首先设定一个分界值,通过该分界值将数组分成左右两部分。
(2)将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。
(3)然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理。
(4)重复上述过程,可以看出,这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。当左、右两个部分各数据排序完成后,整个数组的排序也就完成了。
代码实现
:
static void quickly(int[] a, int b, int c) {
if (b >= c) return;
int i = b, j = c, arrys = a[i];
while (i < j) {
while (i <j && a[j] <= arrys) j--;
if (i < j) a[i++] = a[j];
while (i < j && a[i] >= arrys) i++;
if (i < j) a[j--] = a[i];
}
a[i] = arrys;
quickly(a, b, i - 1);
quickly(a, i + 1, c);
}
测试
:
n=4
输入:1 2 3 4
输出:4 3 2 1