1.插入排序
1.1直接插入排序
给定一组数据,若数据只有一个肯定是有序的,我们将无序数据一个个插入到已有序的数据中。用i遍历无序数据,j遍历有序数据,找到合适插入位置,用tmp存放目标插入数据,将其与j对应数据对比,若大于j就放在j后面,小于j就把j数据往前移一位,j--再次判断。具体代码如下:
java
public static void insertSort(int [] array){
for(int i=1;i<array.length;i++){
int tmp=array[i];//无序数据
int j=i-1;
for(;j>=0;j--){
if(array[j]>tmp){
array[j+1]=array[j];
}
else{
array[j+1]=tmp;
break;
}
}
array[j+1]=tmp;
}
}
1.2希尔排序
希尔排序可以说时直插排序的plus版本,因为直接插入排序的特性是数据越有序排序越快,所以希尔排序会先把数据分成gap组,gap不固定,将每组中的数据进行排序,gap不断减小,最终当gap等于1时排序完毕。具体代码如下:
java
public static void shellSort(int [] array){
int gap=array.length;
while(gap>1){
gap=gap/2;
shell111(array,gap);
}
}
private static void shell(int [] array ,int gap){
for(int i=gap;i<array.length;i++){
int tmp=array[i];
int j=i-gap;
for(;j>=0;j=j-gap){
if(array[j]>tmp){
array[j+gap]=array[j];
}
else {
array[j+gap]=tmp;
break;
}
}
array[j+gap]=tmp;
}
}
2.选择排序
2.1直接选择排序
思想:j从第一个开始遍历,每次遍历找到当前最小的值的下标,存入minIndex,然后跟下标为i的交换,随后i++,直到整个数据遍历完毕。具体代码实现:
java
public static void selectSort(int [] array){
for(int i=0;i<array.length;i++){
int minIndex=i;
for(int j=i+1;j<array.length;j++){
if(array[j]<array[minIndex]){
minIndex=j;//更新最小下标值
}
}
swap(array,minIndex,i);
}
}
2.2堆排序
思想:先把一组数据建成堆(升序就大根堆,降序就小根堆),然后将堆首元素与堆尾元素交换,因为堆首元素一定是max/min值,具体代码如下:
java
public static void heapSort(int[] array){
createHeap111(array);
int end=array.length-1;
while(end>0){
swap(array,end,0);
siftDown111(array,0,end-1);
end--;
}
}
private static void createHeap(int [] array){
int parent=(array.length-2)/2;
for(;parent>=0;parent--){
siftDown111(array,parent,array.length-1);
}
}
private static void siftDown(int[] array, int parent,int end) {
int child=parent*2+1;
while(child<=end){
if(child+1<=end&&array[child]<array[child+1]){
child++;
}
if(array[child]>array[parent]){
swap(array,parent,child);
parent=child;
child=2*parent+1;
}
else{break;}
}
}
3.交换排序
3.1冒泡排序
比较i趟,每一趟都将找出当前范围的最小值/最大值,让它排到末尾,也就是每一趟都定义一个j,j从0开始遍历,如果j大于j+1就叫唤,然后j++,直到循环结束,这样一趟下来就能将一个最值交换到末尾。具体代码实现:
java
public static void bubbleSort(int [] array){
for(int i=0;i<array.length-1;i++){
for(int j=0;j<array.length-1-i;j++){
if(array[j]>array[j+1]){
swap(array,j,j+1);
}
}
}
}
3.2快速排序(挖坑法)
思路;首先找出一个基准值tmp,通常由left对应值担任,当left值赋给tmp后,left就可以看作一个坑,此时right往前走,直到找到比tmp小的值将这个值"填"到left坑中,此时right也成了一个坑,left开始走,直到找到比tmp大的值将其"填"到right,就这样直到left和right相遇,这时将tmp"填"到相遇这个坑中。具体代码如下:
java
public static void rapidSort(int [] array){
rapid111(array,0,array.length-1);
}
private static void rapid(int [] array,int left,int right){
if(left>=right){
return;
}
int mid=getMid111(array,left,right);
rapid111(array,0,mid-1);
rapid111(array,mid+1,right);
}
private static int getMid(int [] array,int left,int right){
int tmp=array[left];
while(left<right){
while(left<right&&array[right]>tmp){
right--;
}
array[left]=array[right];
while(left<right&&array[left]<tmp){
left++;
}
array[right]=array[left];
}
array[left]=tmp;
return left;
}
4.归并排序
思想:将一大组数据分解成小组数据,然后将小组数据有序,然后将小组数据合并为大组数据。
所以整个过程就分为:分割------合并
先说分割:结束条件------left==right。若不满足,则计算mid,通过mid将该范围分割为两部分,具体代码如下:
java
private static void mergeNum(int [] array,int left,int right){
if(left==right){
return ;}
int mid=(left+right)/2;
mergeNum(array,left,mid);
mergeNum(array,mid+1,right);
}
再说合并:假设有两组数据,设计变量s1 e1,s2 e2表示两组数据的头和尾,然后创建一个数组,按从小到大将两组数据放在数组中,然后将这个数组元素复制到array数组中对应的位置。具体代码如下:
java
private static void merge(int [] array,int left,int mid,int right){
int [] num=new int[right-left+1];
int k=0;
int s1=left;
int e1=mid;
int s2=mid+1;
int e2=right;
while(s1<=e1&&s2<=e2){
if(array[s1]<=array[s2]){
num[k++]=array[s1++];
}
else{
num[k++]=array[s2++];
}
}
//必有一败 将剩余组数据放在数组
while(s2<=e2){
num[k++]=array[s2++];
}
while(s1<=e1){
num[k++]=array[s1++];
}
//数组元素有序,还给array
for(int i=0;i<num.length;i++){
array[i+left]=num[i];
}
}
5.计数排序
具体代码如下:
java
public static void countSort(int [] array){
int left=0;
int right=array.length-1;
int maxVal=array[0];
int minVal=array[0];
for(int i=1;i<array.length;i++){
if(array[i]>maxVal){
maxVal=array[i];
}
if(array[i]<minVal){
minVal=array[i];
}
}
int [] number=new int[maxVal-minVal+1];
//初始化计数数组
for(int i=0;i<array.length;i++){
int index=array[i];
number[index-minVal]++;
}
//将计数数组元素打印到原数组中
int index=0;
for(int i=0;i<number.length;i++){
while(number[i]!=0){
array[index]=i+ minVal;
index++;
number[i]--;
}
}
}