1.归并排序
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
接下来看核心思路:
源代码如下:
public class Guibing {
//该方法的作用就是把一个无序数组从中间砍成两半,然后设定两个指针,最初位置分别为两个已经排序序列的起始位置
比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
public void merge(int arr[],int L,int M,int R)
{
int leftsize=M-L;//首先把数组分成两部分,这是左边部分的长度
int rightsize=R-M+1;//这是右边部分的长度
int leftarr[]=new int[leftsize];//为左边数组开辟空间
int rightarr[]=new int [rightsize];//为右边数组开辟空间
int i,j,k;
for(i=L;i<M;i++)//把我们待排序的数组的左部分放入刚才开辟的左空间
{
leftarr[i-L]=arr[i];
}
for(i=M;i<=R;i++){//把我们待排序的数组的左部分放入刚才开辟的右空间
rightarr[i-M]=arr[i];
}
i=0;j=0;k=L;//设定两个指针,最初位置分别为两个已经排序序列的起始位置
while(i<leftsize&&j<rightsize){
if(leftarr[i]<rightarr[j]){
arr[k]=leftarr[i];比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
i++;
k++;
}else{
arr[k]=rightarr[j];
j++;
k++;
}
}
while(i<leftsize){//这说明左边部分还有多的元素,
直接把序列剩下的所有元素直接复制到合并序列尾
arr[k]=leftarr[i];
i++;
k++;
}
while(j<rightsize){//这说明左边部分还有多的元素,
直接把序列剩下的所有元素直接复制到合并序列尾
arr[k]=rightarr[j];
j++;
k++;
}
}
//采用了分治递归的策略
public void mergesort(int arr[],int L,int R){
if(L==R){
return ;
}else{
int M=(L+R)/2;
mergesort(arr, L, M);//先把左边部分排好序(这里面有很多递归)
mergesort(arr, M+1, R);//再把右边部分排好序(这里面有很多递归)
merge(arr, L,M+1, R);//把两个排好序的,做最后一次完整排序
}
}
public static void main(String[] args) {
// int arr[]={2,8,9,10,4,5,6,7};
int arr[]={6,8,10,9,4,5,2,7};
int L=0;
int R=7;
Guibing guibing=new Guibing();
guibing.mergesort(arr, L, R);
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
}
}
运行效果截图:
2.冒泡排序法
原理已经很清晰了
由此可见:N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数,即
冒泡排序法的时间复杂度分析如下:
3.选择排序法
看思路:
见代码如下: