冒泡排序
每次排序都会把最大的元素放到最后一个位置,排序的时候和冒泡很像,一个一个的冒泡。
java
//冒泡排序,每次把一个排好的数字放在最后的位置
public static void bubbleSort(int []nums){
int n= nums.length;
int end=n-1;
while(true){
int exchange=0;//记录每层循环中数据交换的次数
for(int i=0;i<end;i++){
if(nums[i]>nums[i+1]){
swap(nums,i,i+1);
exchange++;
}
}
if(exchange==0)break;//交换次数为零说明交换完毕
}
}
快速排序,使用的是分段排序的方法,每次以第一个元素作为标准值,然后从后往前遍历,找到第一个比标准值小的元素,和low位置交换。接着就从前往后遍历,找到第一个比标准值大的元素,交换位置。
java
//快速排序
public static void quickSort(int[]nums,int i,int j){
if(i<j){
int part=partition(nums,i,j);
quickSort(nums,i,part-1);
quickSort(nums,part+1,j);
}
}
public static int partition(int[]nums,int low,int high){
int tmp=nums[low];//第一个元素作为标准
while(low<high){
//从后往前找到第一个小于tmp的元素
while(low<high&&nums[high]>=tmp){
high--;
}
if(low<high){
nums[low]=nums[high];
}
//从前往后找到第一个大于tmp的元素
while(low<high&&nums[low]<=tmp){
low++;
}
if(low<high){
nums[high]=nums[low];
}
}
nums[low]=tmp;
return low;
}
插入排序,从第二个元素开始,然后往前遍历,如果这个元素比当前索引位置的元素大,这个元素就需要后移动。
java
//插入排序,每次枚举当前位置的元素,然后往前遍历,比自己大的元素往后移动
public static void insertSort(int []nums){
int n=nums.length;
for(int i=1;i<n;i++){
int tmp=nums[i];
int j=i-1;
//往前搜索,遇到比当前元素大的往后移动
while(j>=0&&nums[j]>=tmp){
nums[j+1]=nums[j--];
}
nums[j+1]=tmp;
}
}
希尔排序,步长不是1,而是d。
java
//希尔排序
public static void shellSort(int[]nums){
int len=nums.length;
for(int d=len/2;d>0;d/=2){
for(int i=d;i<len;i++){
int tmp=nums[i];
int j;
for(j=i-d;j>=0;j-=d){
if(nums[j]>=tmp){
nums[j+d]=nums[j];
}else{
break;//退出循环
}
}
nums[j+d]=tmp;
}
}
}
选择排序,每次选择最小的元素,进行交换位置
java
//选择排序,每次找到最小的元素,与当前位置直接交换
public static void selectSort(int[]nums){
int n=nums.length;
for(int i=0;i<n-1;i++){
int k=i;//记录当前的位置
for(int j=i+1;j<n;j++){
//循环找到一个最小的
if(nums[j]<=nums[k])k=j;
}
if(k!=i){
swap(nums,i,k);
}
}
}
堆排序
java
public static void heapSort(int[]nums){
int n=nums.length-1;
//进行筛选,n/2是第一个非叶子节点
for(int i=n/2;i>=0;i--){
heapShift(nums,i,n);
}
//大根堆构建完毕,开始排序,每次从堆顶获取最大的元素放在数组的最后一个位置
for(int i=n;i>0;i--){
int tmp=nums[0];
nums[0]=nums[i];
nums[i]=tmp;
heapShift(nums,0,i-1);
}
}
public static void heapShift(int []nums,int i,int n){
//从i到n是满足大根堆的
int tmp=nums[i];
int j=i*2+1;//左子树节点,完全二叉树
while(j<=n){
if(j<n&&nums[j]<nums[j+1]){
j++;//变成右子树
}
if(tmp>nums[j])break;//筛选结束
nums[i]=nums[j];//大的元素往上移动
i=j;
j=2*j;
}
nums[i]=tmp;
}
归并排序,先分治到数组的个数只有一个的时候,再使用两个数组进行合并
java
public static int[] mergeSort(int[]nums){
return divide(nums,0,nums.length);
}
public static int[]divide(int[]nums,int i,int j){
int m=j-i;
if(j-i==0){
return new int[]{};
}
if(j-i==1){
return new int[]{nums[i]};
}
int[]left=divide(nums,i,i+m/2);
int[]right=divide(nums,i+m/2,j);
return merge(left,right);
}
public static int[]merge(int[]left,int[]right){
int[]p=new int[left.length+right.length];
int k=0;
int i=0;
int j=0;
while(i<=left.length-1&&j<=right.length-1){
if(left[i]<right[j]){
p[k++]=left[i++];
}else{
p[k++]=right[j++];
}
}
while(i<=left.length-1){
p[k++]=left[i++];
}
while(j<=right.length-1){
p[k++]=right[j++];
}
return p;
}
桶排序(计数排序),使用一个数组记录每个元素出现的次数。
maxLength>Math.max(nums)
java
//桶排序,就是使用一个数组,下标的位置就是某个元素
public static void bulkSort(int[]nums,int maxLength){
int[]max=new int[maxLength];
for(int num:nums){
max[num]++;
}
for(int i=0,j=0;i<maxLength;i++){
while(max[i]!=0){
nums[j++]=i;
max[i]--;
}
}
}