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

Java一步一脚—排序(最基本的排序,两种快排,归并排序

2015-10-22 11:39 375 查看
public class Sort {
public static void main(String[] args){
// TODO Auto-generated method stub
int[] a={5,3,2,6,1,4};
Sort s=new Sort();//即使调用类内部的非静态成员,也需要创建该类的对象来调用相应的方法

s.sort(a);

}

public void sort(int[] arr)
{
int temp=0;
for(int i=1;i<arr.length;i++)
{
for(int j=0;j<arr.length-i;j++)
{
if(arr[j]>arr[j+1])
{
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
showArr(arr);
}
public void showArr(int[] arr)
{
for(int i=0;i<arr.length;i++)
System.out.printf("%d\t",arr[i]);
}
}

下面两种快排都是递归思想

public class Sort2 {

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a={5,-2,3,7,8,99,100};
Sort2 ss=new Sort2();
ss.quickSort(a);

}

public void quickSort(int[] a)
{
int n=a.length;
run(a,0, n-1);
showArr(a);
}
public void run(int[] a, int left,int right)
{
int i,j,temp,middle;
i=left;
j=right;
middle=(a[i]+a[j])/2;//中间元素
do{
while(i<right&&a[i]<middle)//从左边开始与中间元素相比,大于的话交换
i++;//满足判断下一个
while(j>left&&a[j]>middle)//从最后开始判断,同样小于中间元素交换
j--;//满足判断下一个
if(i<=j)//当不满足上面两个循环时候执行交换,条件是下标是i<j
{
temp=a[i];
a[i]=a[j];
a[j]=temp;
//交换完继续判断下一个重新进入while循环
i++;
j--;
}
}while(i<=j);//循环条件是当i与j不交错时候
if(left<j)//再从左边开始到中间同样方法排序,知道left与j相等时,表示都递归完
run(a,left,j);//递归思想,传入数组a,然后从left到第一次拍完的j
if(right>i)//从右边到中间重新开始排序
run(a,i,right);//从第一次拍完的i的位置开始到结尾直到,两值相等时
}

public void showArr(int[] a)
{
for(int i=0;i<a.length;i++)
System.out.printf("%d\t", a[i]);
}

}


public class Sort3 {

public static void main(String[] args) {
// TODO Auto-generated method stub
int[] a={5,-2,3,7,8,99,100};
Sort3 ss=new Sort3();
ss.quickSort(a, 0, a.length-1);
ss.showArr(a);
}
public void quickSort(int[] a,int l,int h)
{
int pos;
if(l<h)
{
pos=find(a,l,h);
quickSort(a,l,pos-1);
quickSort(a,pos+1,h);
}
}
public int find(int[] a,int l,int h)
{
int val=a[l];
while(l<h)
{
while(h>l&&a[h]>=val)
h--;
a[l]=a[h];
while(l<h&&a[l]<=val)
l++;
a[h]=a[l];
}
a[l]=val;
return l;
}
public void showArr(int[] a)
{
for(int i=0;i<a.length;i++)
System.out.printf("%d\t", a[i]);
}
}
最后一种归并排序,是我才学习到的,核心算法思想:分,排,排。目前也不算完全理解,先copy上来,慢慢领悟把:
public class Sort4 {

public static void main(String[] args) {
int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
mergeSort(data);
print(data);
}

public static void mergeSort(int[] data) {
sort(data, 0, data.length - 1);
}

public static void sort(int[] data, int left, int right) {
if (left >= right)
return;
// 找出中间索引
int mid = (left + right) / 2;
// 对左边数组进行递归
sort(data, left, mid);
// 对右边数组进行递归
sort(data, mid + 1, right);
// 合并
merge(data, left, mid, right);
}

/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data
*            数组对象
* @param left
*            左数组的第一个元素的索引
* @param center
*            左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right
*            右数组最后一个元素的索引
*/
public static void merge(int[] data, int left, int mid, int right) {
// 临时数组
int[] tmpArr = new int[data.length];
// 右数组第一个元素索引
int rightindex = mid + 1;
// i记录临时数组的索引
int i = left;
// 缓存左数组第一个元素的索引
int leftindex = left;
//while循环条件:left小于等于中间索引,右索引小于right,其实就是左右两个数组索引都要小于其末端索引
while (left <= mid && rightindex<= right) {
// 从两个数组中取出最小的放入临时数组,左数组每个元素与右数组的第一个元素开始比较
if (data[left] <= data[rightindex]) {
tmpArr[i++] = data[left++];
} else {
tmpArr[i++] = data[rightindex++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (rightindex <= right) {
tmpArr[i++] = data[rightindex++];
}
while (left <= mid) {
tmpArr[i++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)这里leftindex就是保存最初的左数组的第一个索引值
while (leftindex<= right) {
data[leftindex] = tmpArr[leftindex++];
}
}

public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}

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