文章目录
算法分类
- 比较类算法:通过比较决定元素的次序,时间复杂度不能突破O(nlogn)。非线性时间比较器
- 非比较类算法:不同比较,可以突破基于比较排序的事件下界。线性时间比较器
1、 冒泡排序(交换排序)
1.1、基本思想
在无序区交换最大元素到最右边,交换n-1躺。
结果:将最大值放到最终位置
1.1、算法具体描述
a) 比较相邻的两个数,如果第二个数大,就交换位置
b) 从左到右进行比较,直到将最大值交换到最右边
c) 依此类推,交换n-1躺
1.2、Java代码实现
public static int[] BubbleSort(int[] arry){
for (int i=0;i<arry.length-1;i++){ //总共交换(arry.length-1)轮,依此将第1,2,3,,,n-1大的数找出来
Boolean flag=false; //没有进行交换
for(int j=0;j<arry.length-1-i;j++){ //每轮交换的起始位置
if(arry[j]>arry[j+1]){ //比较相邻的两元素
swap(arry,j,j+1);
flag=true;
}
}
if(!flag){break;}
}
return arry;
}
2、
3、选择排序(选择排序)
3.1、基本思路
在无序区选择最小值放到最左边,选择n-1躺
3.1、算法具体描述
a) 首先从未排序队列中找到最小元素,存放到第一个位置
b) 然后从未排序队列中找到第二小元素,存放到第二个位置
c) 依此类推,重复n-1躺
3.3、Java实现
/**
* 进行简单选择排序
*/
public static int[] SelectSort(int[] arry){
for (int i=0;i<arry.length-1;i++){ //选择的躺数n-1躺
int min=i; //暂存最小值小标,而不能暂存最小值
for (int j=i+1;j<arry.length;j++){
if(arry[j]<arry[min]){
// arry[min]=arry[j];
min=j;
}
}
swap(arry,min,i);
}
return arry;
}
4、插入排序(区别冒泡和选择,操作有序区进行排序)
4.1、基本思想
向有序区插入相应位置,插入n-1躺。
4.2、算法具体描述
a) 假设第一个元素已经排好序
b) 插入已排好序的有序区,插入n-1躺
c) 若找到比该值大的向后移,直到找到比该值小的。
4.3、Java实现
/**
* 进行插入排序
*/
public static int[] InsertSort(int[] arry){
int pre,curr;
for (int i=1;i<arry.length;i++){ //i表示下标
pre=i-1;
curr=arry[i]; //当前处理的数字
while(pre>=0 && arry[pre]>curr){ //查找比当前数字小的并且右移,然后插入相应的位置
arry[pre+1]=arry[pre];
pre--;
}
arry[pre+1]=curr;
}
return arry;
}
2、快速排序(交换排序)
2.1、基本思路
(分治法)通过一趟排序将数列分割成分组有序的两部分,然后递归的排序子数列
结果:将枢轴放到最终位置
2.2、算法具体实现
a) 选一个 基准,将比基准大的向右移动,将比枢轴小的向左移动
b) 递归的排序子数列
2.3、Java实现
/**
* 进行快速排序:添加两个指针
* 1. 将枢轴放到最终位置,并保持分区有序
* 2. 递归进行排序
*/
public static int[] QuickSort(int[] arry,int low,int hight){
if(low<hight){ //递归跳出条件
int pivot=partition(arry,low,hight);//进行分区,返回枢轴的索引(而不是枢轴的值)
QuickSort(arry,0,pivot-1);
QuickSort(arry,pivot+1,hight);
}
return arry;
}
/**
* 通过枢轴对数组进行划分,划分方式
* 5(low),2,1,7,3,4,8,0(hight)
* 0(low),2,1,7,3,4,8,5(hight)
* 0,2,1,5(low),3,4,8,7(hight)
* 0,2,1,4(low),3,5(hight),8,7
* 0,2,1,4,3,5(low,hight),8,7
* 通过枢轴对数组进行划分,划分方式是从右边找到一个比枢轴小的移动到low位置,从左边找到一个比枢轴大的移动到hight位置
* 5(low),2,1,7,3,4,8,0(hight)
* 0(low),2,1,7,3,4,8,0(hight)
* 0,2,1,7(low),3,4(hight),8,7
* 0,2,1,4,3,4(low,hight),8,7
* 0,2,1,4,3,5(low,hight),8,7
* @return
*/
public static int partition(int[] a,int low,int hight){
int pivot=a[low];//将数组第一个作为枢轴值,将其暂存到某变量
while(low<hight){ //循环跳出条件
while(low<hight && a[hight]>=pivot) --hight; //找到比枢轴小的元素移动=hight(比枢轴大的向左移动,直到找到)
a[low]=a[hight]; //将比枢轴小的移动到右边
while(low<hight && a[low]<=pivot) ++low; //找到比枢轴大的元素=low
a[hight]=a[low]; //将比枢轴大的移动到右边
}
a[low]=pivot; //将枢轴元素存放到最终位置,将交换优化到了移动
return low;
}