十大经典排序算法有
1 冒泡排序 2.选择排序 3.插入排序 4.计数排序 5.希尔排序
6.归并排序 7.堆排序 8.快速排序 9.桶排序 10.基数排序
1.冒泡排序
1.概念:冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
class Test02{
public static void main(String[] args){
//1.选择排序O(n^2)
selectSort();
//2.冒泡排序O(n^2)
bubbleSort();
//3.插入排序O(n^2)
insertSort();
//4.计数排序O(n+m)
countSort();
}
具体代码实现方法
public static void bubbleSort(){
int[] arr={3 44 38 5 47 15 36 26 27 2 46 4 19 50 48};
for(int i=0;i<arr.length-1;i++){//-1是少一轮比较
for(int j=0;j<arr.length-1-i;j++){//-1避免重复比较和角标越界
if(arr[j]>arr[j+1]){
swap(arr,j,j+1); //交换在最后统一
}
}
}
show(arr); //show方法在最后统一写出
}
2.稳定的排序
2.选择排序
1.概念::第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。
具体代码实现
public static void selectSort(){
int[] arr={3 44 38 5 47 15 36 26 27 2 46 4 19 50 48};
for(int i=0;i<arr.length-1;i++){//-1是因为没有必要进行最后一个数字的比较
for(int j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
swap(arr,i,j);//即用-即释放
}
}
}
show(arr);
}
1.比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。
3.插入排序
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。)概念:将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
代码实现
public static void insertSort(){
int[] arr={8,5,9,2,7,4,6,1,3};
int e;
int j;
for(int i=1;i<arr.length;i++){
e=arr[i];
for(j=i;j>0&&arr[j-1]>e;j--){
arr[j]=arr[j-1];
}
arr[j]=e;
}
/*
for(int i=1;i<arr.length;i++){
for(int j=i;j>0&&arr[j-1]>arr[j];j--){
swap(arr,j,j-1);
}
}
*/
show(arr);
}
4.计数排序
概念:1)找出待排序的数组中最大和最小的元素,(2)统计数组中每个值为i的元素出现的次数,存入数组C的第i项
,(3)对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加),(4)反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
(所图片来自runobb.com)
2.代码实现
public static void countSort(){
int[] arr={8,5,9,2,7,4,6,1,3,10,-3,-2,-10};
int min=arr[0];
int max=arr[0];
for(int i=0;i<arr.length;i++){//O(n)
if(arr[i]>max){
max=arr[i];
}
if(arr[i]<min){
min=arr[i];
}
}
int[] nums=new int[max-min+1];
int offset=min;
for(int i=0;i<arr.length;i++){//O(n)
nums[arr[i]-offset]++;
}
int index=0;
for(int i=0;i<nums.length;i++){//O(m)
if(nums[i]!=0){
for(int j=0;j<nums[i];j++){
arr[index++]=i+offset;
}
}
}
show(arr);
}
计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序不是比较排序,排序的速度快于任何比较排序算法。
由于用来计数的数组C的长度取决于待排序数组中数据的范围(等于待排序数组的最大值与最小值的差加上1),这使得计数排序对于数据范围很大的数组,需要大量时间和内存。
5.公共的show方法 打印出来一个数组
public static void show(int[] arr){
//[1,2,3,4,5,6,7,8,9]
String s="[";
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
s+=arr[i]+"]";
}else{
s+=arr[i]+",";
}
}
System.out.println(s);
}
}
6.swap交换方法三种方法
public static void swap(int[] arr,int i,int j){
//1.借助三方变量进行交换
//适用于所有的数据类型 比较通用
/*
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
*/
//2.借助加减法运算进行交换
//只适用于数字相关的数据类型
arr[i]=arr[i]+arr[j];
arr[j]=arr[i]-arr[j];
arr[i]=arr[i]-arr[j];
//3.借助位运算进行交换
//只适用于整数相关的数据类型
/*
int a=3;
int b=7;
a=a^b;
0011
0111
0100
b=a^b;
0100
0111
0011 ->3
a=a^b;
0100
0011
0111 ->7
*/
}
欢迎大佬们给小白我指出错误