您的位置:首页 > 编程语言 > Java开发

java数组排序

2015-07-16 18:44 351 查看
/**

数组排序:

1、选择排序

2、冒泡排序

3、快速排序(转载)

*/

class Arrsort

{

public static void main(String[] args)

{

//System.out.println("Hello World!");

int[] arr={1,3,2,5,7,6,99,354};

int[] arr2={1,3,2,5,7,6,99,354};

printArr(arr);

selectSort(arr);//选择排序

printArr(arr);

bubbleSort(arr2);//冒泡排序

printArr(arr2);

printArr(arr);

selectSort2(arr);//改进选择排序

printArr(arr);

}

//打印数组

public static void printArr(int[] arr)

{

System.out.println("arr=[");

for(int i=0;i<arr.length;i++)

{

if(i!=arr.length-1)

System.out.println(arr[i]+",");

else

System.out.println(arr[i]+"]");

}



}

//冒泡排序,外循环控制循环次数,内循环控制比较个数

public static void bubbleSort(int[] arr)

{



for(int i=0;i<arr.length-1;i++)

{

for (int j=0; j<arr.length-1-i;j++ )//-1:避免越界;-x:外循环每增加一次,内循环比较元素个数递减

{

if(arr[j]>arr[j+1])

swap(arr,j,j+1);

}

}

}

//选择排序

public static void selectSort(int[] arr)

{



for(int i=0;i<arr.length-1;i++)

{

for (int j=i+1; j<arr.length;j++ )

{

if(arr[i]>arr[j])

swap(arr,i,j);

}

}

}

//改进选择排序,使换位次数减少,提供提高性能,

public static void selectSort2(int[] arr)

{



for(int i=0;i<arr.length-1;i++)

{

int num=arr[i];

int index=i;

for (int j=i+1; j<arr.length;j++ )

{

if(num>arr[j])

{

num=arr[j];

index=j;

}

}

if(index!=i)

swap(arr,i,index);



}

}

//交换位置

public static void swap(int[] arr,int a,int b)

{

int temp;

temp=arr[a];

arr[a]=arr;

arr[b]=temp;

}

}

3、快速排序

[b]1、算法概念。

快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。


2、算法思想。

通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

3、实现思路。

①以第一个关键字 K 1 为控制字,将 [K 1 ,K 2 ,…,K n ] 分成两个子区,使左区所有关键字小于等于 K 1 ,右区所有关键字大于等于 K 1 ,最后控制字居两个子区中间的适当位置。在子区内数据尚处于无序状态。

②把左区作为一个整体,用①的步骤进行处理,右区进行相同的处理。(即递归)

③重复第①、②步,直到左区处理完毕。

4该方法的基本思想是:http://www.cnblogs.com/morewindows/archive/2011/08/13/2137415.html
1.先从数列中取出一个数作为基准数。

2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。

3.再对左右区间重复第二步,直到各区间只有一个数。



虽然快速排序称为分治法,但分治法这三个字显然无法很好的概括快速排序的全部步骤。因此我的对快速排序作了进一步的说明:挖坑填数+分治法:

先来看实例吧,定义下面再给出(最好能用自己的话来总结定义,这样对实现代码会有帮助)。



以一个数组作为示例,取区间第一个数为基准数。

0
1
2
3
4
5
6
7
8
9
72
6
57
88
60
42
83
73
48
85
初始时,i = 0; j = 9; X = a[i] = 72

由于已经将a[0]中的数保存到X中,可以理解成在数组a[0]上挖了个坑,可以将其它数据填充到这来。

从j开始向前找一个比X小或等于X的数。当j=8,符合条件,将a[8]挖出再填到上一个坑a[0]中。a[0]=a[8];
i++; 这样一个坑a[0]就被搞定了,但又形成了一个新坑a[8],这怎么办了?简单,再找数字来填a[8]这个坑。这次从i开始向后找一个大于X的数,当i=3,符合条件,将a[3]挖出再填到上一个坑中a[8]=a[3];
j--;



数组变为:

0
1
2
3
4
5
6
7
8
9
48
6
57
88
60
42
83
73
88
85
i = 3; j = 7; X=72

再重复上面的步骤,先从后向前找,再从前向后找

从j开始向前找,当j=5,符合条件,将a[5]挖出填到上一个坑中,a[3] = a[5]; i++;

从i开始向后找,当i=5时,由于i==j退出。

此时,i = j = 5,而a[5]刚好又是上次挖的坑,因此将X填入a[5]。



数组变为:

0
1
2
3
4
5
6
7
8
9
48
6
57
42
60
72
83
73
88
85
可以看出a[5]前面的数字都小于它,a[5]后面的数字都大于它。因此再对a[0…4]和a[6…9]这二个子区间重复上述步骤就可以了。





对挖坑填数进行总结

1.i =L; j = R; 将基准数挖出形成第一个坑a[i]。

2.j--由后向前找比它小的数,找到后挖出此数填前一个坑a[i]中。

3.i++由前向后找比它大的数,找到后也挖出此数填到前一个坑a[j]中。

4.再重复执行2,3二步,直到i==j,将基准数填入a[i]中。

照着这个总结很容易实现挖坑填数的代码:

public class QuickSort {

public static void main(String[] args) {

int[] arr={1,5,9,2,0,11,3,8,12};

quick_sort(arr,0,8);

for(int i=0;i<arr.length;i++)

System.out.println("arr="+arr[i]);

// TODO Auto-generated method stub

}

public static void quick_sort(int[] arr, int l, int r) {

// TODO Auto-generated method stub

if(l<r){//if条件判断防止溢出

int i=l;

int j=r;

int temp=arr[l]; //arr[left]即arr[i]就是第一个坑

while(i<j)

{

// 从右向左找小于temp的数来填arr[i]

while(i<j&&arr[j]>=temp)

j--;

//前面虽然while里判断过,但while最后还有个j--,j--之后可能会出现i=j的情况,所以if不能去掉。

if(i<j)

arr[i++]=arr[j];//将arr[j]填到arr[i]中,arr[j]就形成了一个新的坑

// 从左向右找大于temp的数来填arr[j]

while(i<j&&arr[i]<=temp)

i++;

if(i<j)//同理

arr[j--]=arr[i];//将arr[j]填到arr[i]中,arr[j]就形成了一个新的坑

}

//退出时,i等于j。将temp填到这个坑中。

arr[i] = temp;

quick_sort(arr, l, i - 1); // 递归调用

quick_sort(arr, i + 1, r);

}

}

}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: