冒泡排序:冒泡排序很简单,就是想冒泡一样,让小的数或者大的数往上“冒泡”。(这个大多数人应该都会了,就不在多啰嗦了!)注意!冒泡排序之后,不改变相同数的相对位置不会改变,所以冒泡排序还是有一定的稳定性的。
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[]= {3,5,8,2,0,5,6};
M_sort(a);
System.out.println("冒泡排序后:");
for(int x:a) {
System.out.print(x+" ");
}
}
public static void M_sort(int a[]) {//其时间复杂度为O(n^2)
for(int i=0;i<a.length-1;i++) {
for(int j=0;j<a.length-i-1;j++)
if(a[j]>a[j+1])
merg(a,j,j+1);
}
}
public static void merg(int a[],int m,int n) {
int tem=a[m];
a[m]=a[n];
a[n]=tem;
}
接下来是选择排序,这个的实现过程就是,找到未进行排序中的一个最小值,然后让这个最小值与
未排序的第一个值作交换,一直重复这个过程,直至让这个数组有序。
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[]= {3,5,8,2,0,5,6};
X_sort(a);
System.out.println("选择排序后:");
for(int x:a) {
System.out.print(x+" ");
}
}
public static void X_sort(int a[]) {
for(int i=0;i<a.length;i++) {
int tem=i;
for(int j=i+1;j<a.length;j++) {
if(a[j]<a[tem])
tem=j;
}
merg(a,tem,i);
}
}
public static void merg(int a[],int m,int n) {
int tem=a[m];
a[m]=a[n];
a[n]=tem;
}
归并排序感觉就比较难一点了,该过程利用递归
你可以把递归的过程看做一个黑盒,就是在划分左右的时候,已经对left-mid和mid+1-right位置排好序了(假设是这两个递归完成的这个操作(便于理解才有的这样的假设,实际过程比较复杂)) ,排的顺序如果是增的则两边都为增,如果为减两边都为减。这个时候,你只需要开辟一个辅助数组help,和两个“指针”p1=l,p2=m+1.比较p1和p2谁小,然后将这个小的数放到help数组里,然后将小的这一边向右移动一个位置,直至p1走到m,或者p2走到了r,这个时候,你只需要将剩下一个未走到头的值全部付给help数组就行,然后再把help数组的值传给目标数组。
public static void main(String[] args) {
// TODO Auto-generated method stub
int c[]= {3,5,8,2,0,5,6};
G_sort(c,0,c.length-1);
System.out.println("归并排序后:");
for(int x:c) {
System.out.print(x+" ");
}
}
public static void G_sort(int a[],int left,int right) {//归并排序,其时间复杂度为O(n*logn)
if(left==right)
return ;
int mid=left+(right-left)/2;
G_sort(a,left,mid);
G_sort(a,mid+1,right);//这就相当于是一个黑盒,你可以理解为,以mid为分界线(这个黑盒将mid左右的数排好序)。
mark(a,left,mid,right);
}
public static void mark(int a[],int l,int m,int r) {
int help[]=new int[r-l+1];
int p1=l;
int p2=m+1;
int i=0;
while(p1<=m&&p2<=r) {
help[i++]=a[p1]>a[p2]?a[p2++]:a[p1++];
}
while(p1<=m)
help[i++]=a[p1++];
while(p2<=r)
help[i++]=a[p2++];
for(int j=0;j<help.length;j++) {
a[l+j]=help[j];
}
}
快速排序有好几个版本,今天我们就写一下时间复杂度最低的一个版本。所谓的快速排序,就是以一个数为指标,将大于这个数的所有数放到最右边,小于这个数的数放到最左边,将等于这个数的数放到最中间。那该怎样实现这个过程呢?首先随机生成一个数,其范围在begin-endl之间,将这个位置上的数与endl位置上的数作交换,然后以endl为指标,(还需要定义边界,就是小于指标的数边界left=begin-1(数组最左),大于这个数的边界right=endl()数组最右)从begin开始,如果说begin位置上的数小于指标a[endl],那么让左边界边界加1,然后让左边界上的数与begin交换,然后begin加1;如果begin位置上的数与指标a[endl]上的数相等,只让begin加1就行;如果说begin位置上的数大于指标a[endl],让后让右边界减1,再让begin上的数与右边界上的数加1即可(千万不能让begin加1,因为交换之后begin上的数是一个新的数字,这个数字还未与指标比较过)。接下来上代码。
public static void main(String[] args) {
// TODO Auto-generated method stub
int d[]= {3,5,8,2,0,5,6};
K_sort(d,0,d.length-1);
System.out.println("快速排序后:");
for(int x:d) {
System.out.print(x+" ");
}
}
public static void K_sort(int a[],int begin,int endl) {//快速排序的其中一个版本,其时间复杂度为O(n*logn)
if(endl>begin) {
merg(a,begin+(int)(Math.random()*(endl-begin+1)),endl);
int b[]=partition(a,begin,endl);
K_sort(a,begin,b[0]-1);
K_sort(a,b[1]+1,endl);
}
}
public static int[] partition(int a[],int L,int R) {
int left=L-1;
int right=R;
while(L<right) {
if(a[L]>a[R])
merg(a,L,--right);
else if(a[L]==a[R])
L++;
else
merg(a,L++,++left);
}
merg(a,right,R);
return new int[]{left+1,right};
}
public static void merg(int a[],int m,int n) {
int tem=a[m];
a[m]=a[n];
a[n]=tem;
}
后两个用的递归,不了解递归的可能感觉后两个排序不是很容易理解。
下一篇 二叉树排序和堆排序。
写此篇用于自律,以后会定期更新数据结构和算法,谢谢观看!