一、冒泡排序
冒泡排序是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较相邻两个元素,如果顺序错误就把他们交换过来。
算法步骤:
1)比较相邻的元素。如果第一个比第二个大,就交换他们两个元素。
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
3)针对所有的元素重复以上的步骤,除了最后一个。
4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
冒泡排序代码:
public static void BubbleSort(int[] sort){
int temp = 0; //用于元素交换时的中间变量
int len=sort.length; //len保存数组的长度
for(int i=1;i<len;i++){//循环len-1次,每次循环最后一个数为最大值
for(int j=0;j<len-i;j++){//循环len-i次,比较相邻两个元素
if(sort[j]>sort[j+1]){
// 比较相邻两个元素,如果前者比后者大,交换元素位置,注意边界问题
temp=sort[j];
sort[j]=sort[j+1];//通过中间变量交换元素
sort[j+1]=temp;
}
}
}
}
优化的冒泡排序
可能在前几次就已经排好序,但是在普通冒泡排序中仍然需要一直遍历到最后。
优化措施:设置一个boolean值,如果这一循环发生了交换,则为true,否则为false。即如果这一循环没有发生交换,说明排序已经完成。
public static void BubbleSort(int[] sort){
int temp = 0; //用于元素交换时的中间变量
int len=sort.length; //len保存数组的长度
boolean flag=true;
for(int i=1;i<len;i++){//循环len-1次,每次循环最后一个数为最大值
while(flag){
flag=false;
for(int j=0;j<len-i;j++){//循环len-i次,比较相邻两个元素
if(sort[j]>sort[j+1]){
// 比较相邻两个元素,如果前者比后者大,交换元素位置,注意边界问题
temp=sort[j];
sort[j]=sort[j+1];//通过中间变量交换元素
sort[j+1]=temp;
flag=true;
}
}
}
}
}
二、选择排序
选择排序是一种简单直观的排序算法。
算法步骤:
1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置
2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
3)重复第二步,直到所有元素均排序完毕。
顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
选择排序是不稳定的排序方法。
public static void ChoseSort2(int[] sort){
for(int i=0;i<sort.length-1;i++){
for(int j=i+1;j<sort.length;j++){
if(sort[j]<sort[i]){
int temp=sort[j];
sort[j]=sort[i];
sort[i]=temp;
}
}
}
}
优化选择排序:
每次比较后直接交换位置,增加了排序时间
可以将此元素与其他未排序的元素全部比较之后选出最小的元素再交换。
public static int[] ChoseSort1(int[] intArr){
for(int i=0;i<intArr.length;i++){
int lowIndex = i;
for(int j=i+1;j<intArr.length;j++){
if(intArr[j]<intArr[lowIndex]){
lowIndex = j;
}
} //将当前第一个元素与它后面序列中的最小的一个 元素交换,也就是将最小的元素放在最前端
int temp = intArr[i];
intArr[i] = intArr[lowIndex];
intArr[lowIndex] = temp;
}
return intArr;
}
三、快速排序
快速排序把一个串行分为两个子串行再单独排序。
算法步骤:
1) 从数列中挑出一个元素,称为 “基准”,
2 )重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区操作。
3 )递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。
public static int partition(int []array,int lo,int hi){
int key=array[lo];//选取基点
while(lo<hi){
//从后半向前扫描,元素小于key值时,赋给a[lo]
while(array[hi]>=key&&hi>lo){
hi--;
}
array[lo]=array[hi];
//从后半向前扫描,元素大于key值时,赋给a[hi]
while(array[lo]<=key&&hi>lo){
lo++;
}
array[hi]=array[lo];
}
//循环后lo=hi重合
array[hi]=key;//最后把基准存入
return hi;//返回中间元素的坐标
}
//递归函数一直排序
public static void quickSort(int[] array,int lo ,int hi){
if(lo>=hi){
return ;
}
//进行第一轮排序获取分割点
int index=partition(array,lo,hi);
//排序前半部分
quickSort(array, lo, index-1);
//排序后半部分
quickSort(array,index+1,hi);
}
四、插入排序
直接插入排序
将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据
算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
public static void sort(int[] sort){
for(int i=0;i<sort.length-1;i++){ //从第二个元素开始取出比较
for(int j=i+1;(j>0)&&(sort[j]<sort[j-1]);j--){
swap(sort,j,j-1);
}
}
}
//交换元素方法swap
private static void swap(int[] data, int i, int j) {
int temp = data[i];
data[i] = data[j];
data[j] = temp;
}