排序
LintCode题目:下面分别用几种排序算法进行排序
描述
给一组整数,按照升序排序,使用选择排序,冒泡排序,插入排序或者任何 O(n2) 的排序算法。
样例
样例 1:
输入: [3, 2, 1, 4, 5]
输出: [1, 2, 3, 4, 5]
样例解释:
返回排序后的数组。
样例 2:
输入: [1, 1, 2, 1, 1]
输出: [1, 1, 1, 1, 2]
样例解释:
返回排好序的数组。
冒泡排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers(int[] A) {
int n = A.length;
// write your code here
for(int i = 0;i < n ;i++){
for(int j = 0;j < n - i - 1;j++){
if(A[j] > A[j+1]){
int temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
}
}
}
}
}
需要注意的点:
为什么内循环控制条件为n-i-1?
因为冒泡排序每次比较的是当前j指向的数字和其下一个数字,如果不减一那么会出现数组越界的情况。
选择排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers(int[] A) {
// write your code here
int n = A.length;
for(int i = 0;i < n;i++){
int min = A[i];
int minIndex = i;
for(int j = i+1;j < n;j++){
if(A[j]<min){
min = A[j];
minIndex = j;
}
}
//找到的最小值不在当前位置
if(minIndex!=i){
int temp = A[i];
A[i] = A[minIndex];
A[minIndex] = temp;
}
}
}
}
插入排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers(int[] A) {
// write your code here
int n = A.length;
for(int i = 1;i < n;i++){
for(int j=i;j>0;j--){
if(A[j]<A[j-1]){
int temp = A[j];
A[j] = A[j-1];
A[j-1] = temp;
}
}
}
}
}
希尔排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers(int[] A) {
// write your code here
int n = A.length;
//h是希尔排序的间隔大小
int h = 1;
while(h<n/2){
h = h*2+1;
}
while(h>=1){
for(int i = h;i<n;i++){
for(int j = i;j>=h;j=j-h){
if(A[j]<A[j-h]){
int temp = A[j];
A[j] = A[j-h];
A[j-h] = temp;
}
}
}
h = h/2;
}
}
}
归并排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
int[] mA;
public void sortIntegers2(int[] A) {
// write your code here
int n = A.length;
mA = new int[n];
sort(A,0,n-1);
}
public void sort(int[] A,int low,int high){
if(low>=high){
return;
}
int mid = low + (high-low)/2;
sort(A,low,mid);
sort(A,mid+1,high);
merge(A,low,mid,high);
}
public void merge(int[] A,int low,int mid,int high){
int i = low;
int j = mid+1;
int k = low;
while(i<=mid && j<=high){
if(A[i]<=A[j]){
mA[k++] = A[i++];
}
if(A[i]>A[j]){
mA[k++] = A[j++];
}
}
if(i>mid){
while(j<=high){
mA[k++] = A[j++];
}
}
if(j>high){
while(i<=mid){
mA[k++] = A[i++];
}
}
for(int z = low;z<=high;z++){
A[z] = mA[z];
}
}
}
快速排序
public class Solution {
/**
* @param A: an integer array
* @return: nothing
*/
public void sortIntegers2(int[] A) {
// write your code here
int n = A.length;
sort(A,0,n-1);
}
public void sort(int[] A,int low,int high){
if(low>=high){
return;
}
int position = partition(A,low,high);
sort(A,low,position-1);
sort(A,position+1,high);
}
public int partition(int[] A,int low,int high){
int i = low+1;
int j = high;
int a = A[low];
//i<j && i<=high && j>=low
while(true){
while(A[i]<=a){
if(i>=high){
break;
}
i++;
}
//System.out.println(i);
while(A[j]>a){
if(j<=low){
break;
}
j--;
}
if(i>=j){
break;
}
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
int temp = A[j];
A[j] = A[low];
A[low] = temp;
return j;
}
}
编程中遇到的问题:
首先循环条件和break要用好,不要忘记等值情况下的处理。
学生成绩排序
# include<iostream>
# include<string.h>
# include<algorithm>
using namespace std;
//数组长度,即学生的最大个数
# define N 1000
struct student{
char name[101];
int age;
double grade;
};
student s[N];
void inputMessage(student s[],int n){
for(int i=0;i<n;i++){
cin>>s[i].name>>s[i].age>>s[i].grade;
}
}
void outputMessage(student s[],int n){
for(int i=0;i<n;i++){
cout<<s[i].name<<" "<<s[i].age<<" "<<s[i].grade<<endl;
}
}
bool cmp(student a,student b){
int r;
int c = a.grade-b.grade;
if(c==0){
int cmp = strcmp(a.name,b.name);
return cmp<0;
}else{
return a.grade<b.grade;
}
}
main(){
//数组元素个数
int n;
while(cin>>n){
inputMessage(s,n);
sort(s,s+n,cmp);
outputMessage(s,n);
}
}
解析:
本题中并不是对基本数据类型进行排序,而是自己定义的结构体student类型。但是我们依然可以使用sort函数,只要我们定义一个有关student的比较规则cmp函数,将其传入sort函数的第三个参数位置即可。
注:如果升序那么cmp(a,b)返回a<b,如果是降序则返回a>b。