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

八大排序java源代码

2016-01-13 12:51 453 查看
import java.util.Arrays;

public class Sort {

//排序为从小到大序列

/**

* 冒泡排序:一趟一趟的比较,比较相邻元素的大小,每趟有一个元素沉入最后面的位置

* 属于交换类排序

* 稳定的排序算法

* 平均时间复杂度O(n*n)

* 最坏时间复杂度O(n*n)

* 空间复杂度O(1)

* n较小时适用

*/

public static void bubbleSort(int[] array, int off, int len) {

System.out.println("BubbleSort()");

for (int i=1; i<len; i++ ) {//第i趟比较

boolean isSorted = true;//检测是否有交换

for (int j=off; j<off+len-i ; j++){

if (array[j+1]<array[j]){

swap(array, j, j+1);

isSorted = false;//有交换

}

}

if (isSorted == true)//无交换跳出循环,完成排序

break;

}

}

/**

* 直接插入排序:每一轮第i个元素跟前面的i-1个元素从后向前比较,一直比较到合适插入的位置

* 属于插入类排序

* 稳定的排序算法

* 平均时间复杂度O(n*n)

* 最坏时间复杂度O(n*n)

* 空间复杂度O(1)

* 大部分有序时适用

*/

public static void insertSort(int[] array, int off, int len) {

System.out.println("InsertSort()");

int i,j,current;//current记录当前插入元素

for (i=off+1; i<off+len; i++) {//array[i]待插入元素,j为比较元素的下标

for (j=i-1, current = array[i]; j>=off && array[j]>current; j--) {

array[j+1] = array[j];

}

array[j+1] = current;

}

}

/**

* 直接选择排序:第i轮选择剩余最小的元素放入到第i的位置上

* 属于选择类排序

* 不稳定的排序算法 :如58529第一轮选择交换5和2,破换了原来两个5的顺序

* 平均时间复杂度O(n*n)

* 最坏时间复杂度O(n*n)

* 空间复杂度O(1)

* 当n较小时适用

*/

public static void selectSort(int[] array, int off, int len) {

for (int i=off; i<off+len-1; i++) {

int minIndex = i, min = array[i];//最小元素及下标

for(int j=i; j<off+len; j++) {//j为所有待选择元素

if (array[j] < min) {//array[j]更小

min = array[j];

minIndex = j;

}

}

swap(array, minIndex, i);//选择最小元素放入array[i]

}

}

/**

* 快速排序:递归算法,将较大的一组换到后面去,较小的一组在前面,前面和后面的分别再递归调用

* 属于交换类排序

* 不稳定的排序算法 :如35512第一轮时前面的5和后面的2换位置,后面的5和1换位置,位置顺序被破坏

* 平均时间复杂度O(n*log2n)

* 最坏时间复杂度O(n*n)

* 空间复杂度O(1)

* n较大 时适用

*/

public static void quickSort(int[] array, int off, int len) {

if (len <= 1)

return;

if (len == 2)//长度大于三才进行划分

if (array[off] > array[off+1]){

swap(array, off, off+1);

return;

}

int start = off + 1, end = off + len - 1;//交换的开始和结束位置

int middleV = array[off];//可以将off和 off+len-1和off+(len-1)/2三个元素中间的赋值

while(start < end) {

while (array[start] < middleV && start < end)

start++;

while (array[end] > middleV && end > start)

end--;

if (start < end) {

swap(array, start, end);

start++;

end--;

}

}

int mid = off;

if (array[off] > array[end]){

swap(array, end, off);

mid = end;}

quickSort(array, off, mid-off);

quickSort(array, mid+1, len-mid+off-1);

}

/**

* 希尔排序:分组交换的思想,先分组,后交换排序

* 属于交换类排序

* 不稳定的排序算法 :分组之后交换打破了稳定性

* 平均时间复杂度O(n*log2n)

* 最坏时间复杂度O(n^s) 1<s<2

* 空间复杂度O(1)

* n较大时适用

*/

public static void shellSort(int[] array, int off, int len){

int d = len / 2;//组内元素的间隔

while(d >= 1) {//直到退化到bubble为止

shellSortDivision(d,array, off, len);

d /= 2;

}

}

private static void shellSortDivision(int d, int[] array, int off, int len) {

// TODO Auto-generated method stub

for (int i = 0; i < d ; i++) {//第i个分组

for (int j=1; j<=(len-1-i)/d; j++) {//分组内bubble

boolean isSorted = true;

for(int k=off+i; k+d<=off+len-(j-1)*d-1; k+=d){

if (array[k] > array[k+d]) {

swap(array, k, k+d);

isSorted = false;

}

}

if (isSorted == true)

break;

}

}

}

/**

* 归并算法:分而治之的思想

* 属于归并类排序

* 稳定的排序算法

* 平均时间复杂度O(n*log2n)

* 最坏时间复杂度O(n*log2n)

* 空间复杂度O(n)

* n较大时适用

*/

public static void MergeSort(int[] array, int off, int len) {

if (len < 2)

return;

else if (len == 2){

if (array[off] > array[off+1])

swap(array, off, off+1);

return;

}

else {

int middle = off + (len-1)/2;

MergeSort(array, off, middle-off+1);

MergeSort(array, middle+1, len-middle+off-1);

Merge(array,off,middle,off+len-1);

}

}

public static void Merge(int[] array, int left, int middle, int right) {

int l = left, r = middle+1, count = 0;

int[] newArray = new int[right-left+1];

while(l <= middle && r <= right) {

if (array[l] < array[r])

newArray[count++] = array[l++];

else

newArray[count++] = array[r++];

}

while (l <= middle)

newArray[count++] = array[l++];

while (r <= right)

newArray[count++] = array[r++];

for(int i=left,j=0; i<=right; i++) {

array[i] = newArray[j++];

}

// array = newArray;

}

/**

* 堆算法:大根堆a[i] > a[2*i],a[i] > a[2*i+1],先建大根堆,然后不断的:取最大的,调整

* 属于选择类排序

* 不稳定的排序算法:在调整位置时打破了稳定性

* 平均时间复杂度O(n*log2n)

* 最坏时间复杂度O(n*log2n)

* 空间复杂度O(1)

* n较大时适用,选择前i大时适用

*/

public static void heapSort(int[] array, int off, int len) {

buildHeap(array,off, len);

for (int i = 0;i < len; i++) {

swap(array,off,off+len-i-1);//将大根堆最大元素与最后面的位置做交换

shiftDown(array, off, len-i-1, 0);//始终调整第一个元素

}

}

private static void buildHeap(int[] array, int left, int len) {

int pos= len/2 - 1;//从第一个非叶子节点开始

for(int i=pos;i>=0;i--)

{

shiftDown(array,left,len,i); //调整第i个非叶子节点

}

}

private static void shiftDown(int[] array, int left, int len, int pos) {

// TODO Auto-generated method stub

int tmp = array[left+pos];

int indexLC = pos*2 + 1, index;//左孩子

while(indexLC < len) {//判断孩子是否存在

if (indexLC+1 < len && array[left+indexLC]<array[left+indexLC+1])

index = indexLC + 1;//右孩子大

else

index = indexLC;//左孩子大

if(tmp < array[left+index]) {//交换

array[left+pos] = array[left+index];

pos = index;//交换后大值继续跟孩子比较

indexLC = pos*2 + 1;

}else break;

}

array[left+pos] = tmp;//跟目标交换完成

}

/**

* 基数排序

* 稳定的排序算法

* 最差时间复杂度是 O(k·n)

* 空间复杂度O(k·n)

* 多个刻度指标时适用

* @param array

* @param radix 基数

* @param distance 几遍

*/

private static void radixSort(int[] array,int radix, int distance) {

//array为待排序数组

//radix,代表基数

//代表排序元素的位数

int length = array.length;

int[] temp = new int[length];//用于暂存元素

int[] count = new int[radix];//用于统计基数内元素个数

int divide = 1;

for (int i = 0; i < distance; i++) {

System.arraycopy(array, 0,temp, 0, length);

Arrays.fill(count, 0);

for (int j = 0; j < length; j++) {

int tempKey = (temp[j]/divide)%radix;

count[tempKey]++; //基数选中计数

}

for (int j = 1; j < radix; j++) {

count [j] = count[j] + count[j-1];//累计计数

}

for (int j = length - 1; j >= 0; j--) {

int tempKey = (temp[j]/divide)%radix;

count[tempKey]--;//从后往前赋值

array[count[tempKey]] = temp[j];

}

divide = divide * radix;

}

}

//交换两个元素

private static void swap(int[] array, int a, int b) {

int t = array[a];

array[a] = array;

array[b] = t;

}

//打印数组

private static void printArray(String s, int[] array, int off, int len) {

System.out.print(s);

for(int i=off; i<off+len; i++) {

if (i == off)

System.out.print("[" + array[i] + ",");

else if (i == off+len-1)

System.out.print(array[i]);

else

System.out.print(array[i] + ",");

}

System.out.println("]");

}

private static int getMiddleIndexOfThreeElement(int[] array,int a, int b, int c) {

if (array[a] < array[b]) {

if (array[b] < array[c])

return b;

else if (array[c] < array[a])

return a;

else return c;

}else {

if (array[a] < array[c])

return a;

else if (array[c] < array[b])

return b;

else return c;

}

}

public static int getMiddle(int[] list, int low, int high) {

int tmp = list[low]; //数组的第一个作为中轴

while (low < high) {

while (low < high && list[high] > tmp) {

high--;

}

list[low] = list[high];//比中轴小的记录移到低端

while (low < high && list[low] <= tmp) {

low++;

}

list[high] = list[low]; //比中轴大的记录移到高端

}

list[low] = tmp; //中轴记录到尾

return low; //返回中轴的位置

}

public static void quickSort2(int[] array, int low, int high) {

if (low < high) {

int middle = getMiddle(array, low, high); //将list数组进行一分为二

quickSort2(array, low, middle - 1); //对低字表进行递归排序

quickSort2(array, middle + 1, high); //对高字表进行递归排序

}

}

[b][java]
view
plaincopy

/**

* @param args

*/

public static void main(String[] args) {

// TODO Auto-generated method stub

int[] array = {5,7,8,5,21,5,7,1,23,53,6,47,7,2,4,74,7};

printArray("排序前:", array, 0, array.length);

Sort.heapSort(array, 0, array.length);

printArray("排序后:", array, 0, array.length);

}

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