插入排序:使用双重for循环,外循环从i=1开始遍历,内循环从j=i开始遍历到0.如果j<j-1则交换否则退出内循环。–稳定
public static void insertSort(int[] index){
for(int i=1;i<index.length;i++){
for(int j=i;j>0;j--){
if(index[j]<index[j-1])
swap(index,j-1,j);
else
break;
}
}
}
希尔排序:插入排序的进阶,首先需要维持一个增量序列,这里选择2n-1序列1,3,7····。遍历该序列中的数作为增量进行插入排序。–不稳定
public static void shellSort(int[] index){
int n=0;//序列长度
while((Math.pow(2,n+1)-1)<index.length)
n++;
while(n>0){
int increase=(int)Math.pow(2,n)-1;//double->int
for(int i=increase;i<index.length;i+=increase){
for(int j=i;j>=increase;j-=increase){
if(index[j]<index[j-increase])
swap(index,j,j-increase);
else
break;
}
}
n--;
}
}
选择排序:使用双重for循环,外循环从i=0开始,内循环从i+1开始,内循环遍历一次选择出从i到length的最小值,然后与数组下标为i的值交换。–不稳定
public static void selectSort(int[] index){
for(int i=0;i<index.length-1;i++){
int temp=i;
for(int j=i+1;j<index.length;j++){
if(index[j]<index[temp])
temp=j;
}
swap(index,i,temp);
}
}
堆排序
特性:父节点=子节点/2-1;左节点=父节点+1,右节点=父节点+2。
过程:从第一个非叶子节点开始遍历调整行程大顶堆;循环将第一个元素与循环中最后一个元素交换,然后进行调整。–不稳定
public static void heapSort(int[] index){
for(int i=index.length/2-1;i>=0;i--){//从第一个非叶子节点开始建堆
adjustHeap(index,i,index.length);
}
for(int i=index.length-1;i>0;i--){
swap(index,0,i);//交换元素
adjustHeap(index,0,i);//从第一个元素调整到i
}
}
public static void adjustHeap(int[] index,int s,int e){
int temp=s;
for(int i=s*2+1;i<e;i=i*2+1){//从起始节点的左节点开始调整
if(i+1<e&&index[i+1]>=index[i])//如果右节点存在且大于左节点值
i++;
if(index[i]>index[temp]){
swap(index,i,temp);
temp=i;//从i节点开始下一轮遍历
}else{
break;
}
}
}
冒泡排序:使用双重for循环,外循环从i=length-1开始,内循环从j=0开始,内循环中如果j>j+1则交换,一次外循环在数组末尾得到一个最大值。–稳定
public static void bubbleSort(int[] index){
for(int i=index.length-1;i>0;i--){
for(int j=0;j<i;j++){
if(index[j]>index[j+1])
swap(index,j,j+1);
}
}
}
快速排序:选择一个基数作为比较,比基数小的在前面,大的在后面,递归对数组进行划分排序。如果选择当前段最后一个元素作为基数则先从段头开始找比基数大的交换,再从段尾找比基数小的交换。–不稳定
public static void quickSort(int[] index,int left,int right){
if(left<right){
int p=partition(index,left,right);
quickSort(index,left,p-1);
quickSort(index,p+1,right);
}
}
public static int partition(int[] index,int left,int right){
int radix=index[right];
while(left<right){
while(index[left]<=radix&&left<right)
left++;
index[right]=index[left];
while(index[right]>=radix&&left<right)
right--;
index[left]=index[right];
}
index[left]=radix;
return left;
}
归并排序:递归将数组进行划分合并。会用到空间N。–稳定
public static void mergerSort(int[] index,int left,int right){
if(left<right){
int mid=(left+right)/2;
mergerSort(index,left,mid);
mergerSort(index,mid+1,right);
merge(index,left,mid,right);
}
}
public static void merge(int[] index,int left,int mid,int right){
int[] temp=new int[index.length];
int i=left,j=mid+1,count=0;
while(i<=mid&&j<=right){
temp[count++]=index[i]<index[j]?index[i++]:index[j++];
}
while(i<=mid){
temp[count++]=index[i++];
}
while(j<=right){
temp[count++]=index[j++];
}
count=0;
for(int k=left;k<=right;k++){
index[k]=temp[count++];
}
}
基数排序:先从待排序数组找到最大值,得到其位数,然后以位数作为循环条件,新建一个10位整形数组temp用于存放当前数组当前位的值,然后对temp进行累加。再新建一个长度N的整形数组interim对当前位进行排序。最后将interim中的顺序赋值给待排序数组。–稳定
public static void radixSort(int[] index){
int max=Integer.MIN_VALUE;
for(int i:index)
if(i>max)
max=i;
int len=(max+"").length(),d=1;//len为最大数长度,d为除数用来控制当前排序位数
while(len>0){
int[] num=new int[10];
for(int i:index)
num[i/d%10]++;
for(int i=1;i<num.length;i++)
num[i]+=num[i-1];
int[] temp=new int[index.length];
for(int i=index.length-1;i>=0;i--){
temp[--num[index[i]/d%10]]=index[i];
}
for(int i=0;i<index.length;i++)
index[i]=temp[i];
d*=10;
len--;
}
}