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

java常用排序算法总结

2017-12-29 15:17 295 查看
1.  二分查找算法(默认数组从小到大排序)

package sort;
/**
* 二分查找算法
* @author zz
* 递归算法
*/
public class BinarySearch {
public static int binSearch(int[] a, int start,int end, int key) {
//每次都找到中间的那个索引
int mid=(end-start)/2+start;
//查询完毕
if(start>end){
return -1;
}
if(a[mid]==key){
return mid;
}
//要找的值大于中值得话,就从中值往后查找。
if(key>a[mid]){
return binSearch(a, mid+1, end, key);
}
//要找的值小于中值得话,就从中值往前查找。
if(key<a[mid]){
return binSearch(a, start, mid-1, key);
}
return -1;

}
public static void main(String[] args) {
int srcArray[] = {1,3,5,7,9,11,13,15,17};
System.out.println(binSearch(srcArray, 0, srcArray.length - 1, 7));
}
}
2.  冒泡排序算法

package sort;

import java.util.Arrays;

/**
* 冒泡排序算法
* @author zz
* 将序列划分为无序和有序区,不断通过交换较大元素至无序区尾完成排序。
*/
public class BubbleSort {
private static void bubbleSort(int[] a) {
for (int i = 1; i <= a.length - 1;i++) {
for (int j = 0; j <= a.length-1 - i; j++) {
//每次循环比较前后两个值,如果大于后面就交换。
//第一次j循环是到0-a.length-1,之后是0-a.length-2,不停往前缩进,一直到0,所有序列排序完毕
if (a[j] > a[j + 1]) {
swap(a, j, j + 1);
}
}
}
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
public static void main(String[] args) {
int srcArray[] = {4,5,8,1,7,18,15,13,16,17};
bubbleSort(srcArray);
System.out.println(Arrays.toString(srcArray));
}
}
3.  堆排序

package sort;

import java.util.Arrays;

/**
* 堆排序
* @author zz
* 利用大根堆或小根堆思想,首先建立堆,然后将堆首与堆尾交换,堆尾之后为有序区。
* (length/2,length)之后都是子节点,之前都是非子节点。
* Parent(i)=(i-1)/2
* Left(i)=2*i+1
* Right(i)=2*i+2
* 将父节点和子节点比较,如果小就交换
*/
public class HeapSort {
private static void heapSort(int[] a) {
// 先创建大堆,从第一个非叶子结点开始调整,然后依次调整
for (int i = a.length / 2-1; i >= 0 ; i--) {
//三个参数,第一个:要排序的数组;第二个:要放入堆中的元素索引;第三个:需要维护的堆长度
Largeheap(a, i, a.length);
}
// 调整大堆,将最大的元素调整到未排好序的部分的末尾
for (int i = a.length - 1; i >=0 ; i--) {
swap(a, 0, i);
Largeheap(a, 0, i);
}
}
private static void Largeheap(int[] a, int i, int n) {
int temp;//记录节点值
int child;//记录子节点最大值
for(temp=a[i];i*2+1<n;i=child){
child=i*2+1;//左孩子
//先比较左右孩子,child找到最大的孩子
if(
c76f
child!=n-1&&a[child+1]>a[child]){
child++;
}
if(temp<a[child]){
swap(a, i, child);
//交换完毕,子节点又变了,所以要再次循环排序
}else{
break;
}
}
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
public static void main(String[] args) {
int srcArray[] = {4,5,2,8,1,19,7,18,15,13,16,17};
heapSort(srcArray);
System.out.println(Arrays.toString(srcArray));
}
}
4.  插入排序

package sort;

import java.util.Arrays;

/**
* 插入排序
* @author zz
*
*/
public class InsertSort {
private static void insertSort(int[] a) {
int temp;
for(int i=1;i<a.length;i++){
//保留要比较的值
temp=a[i];
for(int j=i;j>0&&temp<a[j-1];j--){
//每次比较之后发现小了,就交换顺序
swap(a, j, j-1);
}
}
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
public static void main(String[] args) {
int srcArray[] = {4,5,2,8,1,19,7,18,15,13,16,17};
insertSort(srcArray);
System.out.println(Arrays.toString(srcArray));
}
}
5.  归并排序

package sort;

import java.util.Arrays;
/**
* 归并排序
* @author zz
* 先一分为2,分别排序完毕后再归并。
* 用一个复制数组保存数组的顺序。
*/
public class MergeSort {

public static void main(String[] args) {
int srcArray[] = {4,5,8,1,7,18,15,13,16,17};
int array[]=new int[srcArray.length];
mergeSort(srcArray,array,0,srcArray.length-1);
System.out.println(Arrays.toString(srcArray));
}
public static void mergeSort(int[] a,int[] b,int start,int end){
if(start<end){
int mid=(start+end)/2;
//递归先排序左边
mergeSort(a, b, start, mid);
//递归排序右边
mergeSort(a, b, mid+1, end);
//递归整合排序好的左边和右边
mergeAll(a,b,start,mid+1,end);
}
}
public static void mergeAll(int[] a,int[] b,int leftstart,int middle,int rightend){
int numbers=rightend-leftstart+1;
int leftend=middle-1;
int rightstart=middle;
//temp表示数组b的索引
int temp=leftstart;
while(leftstart<=leftend&&rightstart<=rightend){
if(a[leftstart]<=a[rightstart]){
b[temp]=a[leftstart];
temp++;
leftstart++;
}else{
b[temp]=a[rightstart];
temp++;
rightstart++;
}
}
//当左边未循环完,右边循环完时,剩下的左边都依次添加到b[]里,因为左边本身是排序好的
while (leftstart<=leftend) {
b[temp++]=a[leftstart++];

}
//当右边未循环完,左边循环完时,剩下的右边都依次添加到b[]里,因为右边本身也是排序好的
while (rightstart<=rightend) {
b[temp++]=a[rightstart++];

}
//将排序好的数组b依次赋值给a数组
for(int i=0;i<numbers;i++,rightend--){
a[rightend]=b[rightend];
}
}

}
6.  快速排序

package sort;

import java.util.Arrays;
/**
* 快速排序
* @author zz
* 不断寻找一个序列的中点,然后对中点左右的序列递归的进行排序,直至全部序列排序完成,使用了分治的思想。
*/
public class QuickSort {

public static void main(String[] args) {
int srcArray[] = {4,5,8,1,7,18,15,13,16,17};
quickSort(srcArray,0,srcArray.length-1);
System.out.println(Arrays.toString(srcArray));
}
public static void quickSort(int[] a,int start,int end){
//设置边界(递归算法必须要的)
if(start<end){
//设置一个标记值(很重要)
int temp=a[start];
int i=start;
int j=end;
while(i<j){
//从右边开始往左边找,找第一个比标记值小的数,没找到,j标签继续往左
while(i<j&&a[j]>=temp){
j--;
}
//找到j的值,将它的值给i
a[i]=a[j];
//从左边开始往右边找,找第一个比标记值大的数,没找到,i标签继续往右
while(i<j&&a[i]<=temp){
i++;
}
//找到i的值,将它的值给j
a[j]=a[i];

}
//当i=j时结束这一轮,将i此时的位置替换成标记值,开始快速排序左边和右边
a[i]=temp;
quickSort(a, start, i-1);
quickSort(a, i+1, end);
}
}

}
7.  选择排序

package sort;

import java.util.Arrays;

/**
* 选择排序
* @author zz
* 将序列划分为无序和有序区,寻找无序区中的最小值和无序区的首元素交换,有序区扩大一个,循环最终完成全部排序
*/
public class SelectSort {

public static void main(String[] args) {
int srcArray[] = {4,5,8,1,7,18,15,13,16,17};
selectSort(srcArray);
System.out.println(Arrays.toString(srcArray));
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
public static void selectSort(int []a){
//设置最小值的索引
int temp;
for(int i=0;i<a.length;i++){
temp=i;
//从i往后找,如果找到小的,就赋值给temp
for(int j=i+1;j<a.length;j++){
if(a[j]<a[temp]){
temp=j;
}
}
swap(a, i, temp);
}
}

}
8.  希尔排序

package sort;

import java.util.Arrays;

/**
* 希尔排序
* @author zz
*
*/
/*
* 先将序列按增量划分为元素个数相同的若干组,使用直接插入排序法进行排序,然后不断缩小增量直至为1,最后使用直接插入排序完成排序。
* 增量的选择以及排序最终以1为增量进行排序结束。
*/
public class ShellSort {
public static void main(String[] args) {
int srcArray[] = {4,5,8,1,7,18,15,13,16,17};
shellSort(srcArray);
System.out.println(Arrays.toString(srcArray));
}
private static void swap(int[] a, int x, int y) {
int tmp = a[x];
a[x] = a[y];
a[y] = tmp;
}
private static void shellSort(int[] a) {
//gap每次分组的索引差值
int gap;
for(gap=a.length/2;gap>0;gap/=2){
//循环gap之后的值,如果发现比它对应的gap之前的值小的话,叫交换。
for(int i=gap;i<a.length;i++){
if(a[i]<a[i-gap]){
swap(a, i, i-gap);
}
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: