Java实现的9种排序方法

详见代码。

package com.java.sort;

import java.util.Arrays;

public class Sort {

/**
* 冒泡排序
*
* @param array
*/
public static void bubble(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}

/**
* 选择排序
*
* @param array
*/
public static void selection(int[] array) {
for (int i = 0; i < array.length; i++) {
int min = i;// the index of minimum number
for (int j = i + 1; j < array.length; j++) {
if (array[j] < array[min]) {
min = j;
}
}

if (i != min) {
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
}
}

/**
* 从index=1开始,然后index+1,一直到index=array.length-1。每次比较排序index。 插入排序的递归实现,尾递归
*
* @param array
* @param index
*/
public static void insertion1(int[] array, int index) {
if (index > 0 && index < array.length) {
int key = array[index];
int i = index - 1;
for (; i >= 0 && array[i] > key; i--) {
array[i + 1] = array[i];
}
array[i + 1] = key;
insertion1(array, index + 1);
}
}

/**
* 插入排序 使用场合:数组越接近于有序,插入排序所需做的工作越少
*
* @param array
*/
public static void insertion(int[] array) {
for (int i = 1; i < array.length; i++) {
int key = array[i];
int j = i - 1;
for (; j >= 0 && array[j] > key; j--) {
array[j + 1] = array[j];
}
array[j + 1] = key;
}
}

/**
* 希尔排序 改进的插入排序算法
*
* @param array
*/
public static void shell(int[] array) {
for (int space = array.length / 2; space > 0; space /= 2) {
space = (space % 2 == 0 ? (space + 1) : (space));// 为了来取消那些space为偶数的情况。因为如果不排除这一项,在排序的时候会有重复的排序.
for (int i = 0; i < space; i++) {
sort_array_space(array, i, space);
}
}
}

/**
* 为了辅助shell排序而设计的,类似于插入排序,只不过加入了space
*
* @param array
* @param first
* @param space
*/
private static void sort_array_space(int[] array, int first, int space) {
for (int i = first + space; i < array.length; i += space) {
int key = array[i];
int j = i - space;
for (; j >= first && array[j] > key; j -= space) {
array[j + space] = array[j];
}
array[j + space] = key;
}
}

/**
* 归并排序的主函数。
* 为了让调用变得简单,实际上可以直接使用第二个主函数
* 在java中,sort(Object[] arr)使用便是归并排序
* 归并排序的效率是 nlog2n(2是底数),缺点是需要另外一个数组
* @param array
*/
public static void merge(int[] array){
mergeSort(array,0,array.length-1);
}

/**
* 归并排序第二个主函数
* @param array
* @param left
* @param right
*/
private static void mergeSort(int[] array, int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
mergeSort(array, left, middle);
mergeSort(array, middle + 1, right);
mergeArray(array, left, middle, right);
}
}

/**
* 将 array 数组中left 到 right的内容进行排序,并
* @param array
* @param left
* @param middle
* @param right
*/
private static void mergeArray(int[] array, int left, int middle, int right) {
int[] temp = new int[array.length];
int i = left;
int j = middle + 1;
int index = left;

while ((i <= middle) && (j <= right)) {
if (array[i] <= array[j]) {
temp[index++] = array[i++];
} else {
temp[index++] = array[j++];
}
}

if (i > middle) {
for (int k = j; k <= right; k++) {
temp[index++] = array[k];
}
} else {
for (int k = i; k <= middle; k++) {
temp[index++] = array[k];
}
}

for (int k = left; k <= right; k++) {
array[k] = temp[k];
}
}

/**
* 快速排序的主要入口
* Java中对于基本数据类型使用的是快速排序 sort(type[] array)
* @param array
*/
public static void quick(int[] array){
int p = 0;
int r = array.length-1;
qsort(array,p,r);
}

/**
* 快速排序主函数
* @param array
* @param p
* @param r
*/
private static void qsort(int array[], int p, int r) {
if (p < r) {
int q = partition(array, p, r);
qsort(array, p, q - 1);
qsort(array, q + 1, r);
}
}

/**
* 进行一次排序,并得到分支点
* 过程如下:
* 对p到r位置上的元素进行一一排序(标记位置由i来负责)
* index负责交换位置的确定。没交换一次位置,index++
* for循环结束的时候,比key小的元素会都在index的左边
* 这样再将index和r位置上的两个元素交换
* @param array
* @param left
* @param right
* @return
*/
private static int partition(int array[], int left, int right) {
int key = array[right];
int index = left;
for (int i = left; i < right; i++) {
if (array[i] <= key) {//不关是否交换,index都要增加
if(i != index){//避免交换相同的元素,不过index还是要增加的。
swap(array, index, i);
}
index++;
}
}
swap(array, index, right);
return index;
}

private static void swap(int a[], int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}

/**
* 桶式排序
*
* @param array
*/
public static void bucket(int[] array) {

}

/**
* 基数排序
* @param array
*/
public static void base(int[] array){

}


public static void main(String[] args) {
int[] array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
bubble(array);
System.out.println("bubble:\t\t" + Arrays.toString(array));

array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
selection(array);
System.out.println("selection:\t" + Arrays.toString(array));

array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
insertion(array);
System.out.println("insertion:\t" + Arrays.toString(array));

array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
shell(array);
System.out.println("shell:\t\t" + Arrays.toString(array));

array = new int[] { 3, 4, 5, 2, 6, 7, 1, 9, 8, 10 };
merge(array);
System.out.println("merge:\t\t" + Arrays.toString(array));

array = new int[] { 3, 5, 2, 6, 7, 1, 9, 8, 10, 4};
quick(array);
System.out.println("quick:\t\t" + Arrays.toString(array));
}
}





/**
* @author Yuanbo Han
*/
public class HeapSort {

private double[] elements = new double[10];
private int size = 0;

private HeapSort(){
this.elements = new double[10];
this.size = 0;
}

public void add(double e){
if(size + 1 > elements.length){
int newCapacity = elements.length * 3 / 2 + 1;
double[] newElements = new double[newCapacity];
System.arraycopy(elements, 0, newElements, 0, size);

newElements[size++] = e;
elements = newElements;
}else{
elements[size++] = e;
}
}

public void heapsort(){
for(int i=0;i<size;i++){
int length = size - i;
this.heapsort(length);
}
}

/**
* 对前length个数据进行排序,得到最大的数据为index = 0,然后跟index = length-1的数据进行交换
* @param length
*/
private void heapsort(int length){
int index = length / 2 - 1;
for(int i=index;i>=0;i--){
int head = i;
for(;;){//进行交换之后,子树可能不是最大堆,所以要for循环进行重构最大堆
int max = head;
int left = 2 * head + 1;
int right = 2 * head + 2;
if(left < length && elements[max] < elements[left]){
max = left;
}
if(right < length && elements[max] < elements[right]){
max = right;
}
if(max != head){
double tmp = elements[max];
elements[max] = elements[head];
elements[head] = tmp;
head = left;
}else{
break;
}
}
}

double tmp = elements[0];
elements[0] = elements[length-1];
elements[length-1] = tmp;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0;i<size;i++){
sb.append(elements[i] + ", ");
}
if(size > 0){
sb = new StringBuilder(sb.substring(0, sb.length() - 2));
}
sb.append("]");
return sb.toString();
}

public static void main(String[] args) {
HeapSort hs = new HeapSort();
hs.add(15);
hs.add(60);
hs.add(72);
hs.add(70);
hs.add(56);
hs.add(32);
hs.add(62);
hs.add(92);
hs.add(45);
hs.add(30);
hs.add(65);

hs.heapsort();
System.out.println(hs);

}
}



向一个已经排好序的数组中插入新的数据,使用二分查找来进行位置确定,时间复杂度为(log N)。


/**
* @author Yuanbo Han
*/
public class Sort {

private double[] elements = new double[10];
private int size = 0;

private Sort(){
this.elements = new double[10];
this.size = 0;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0;i<size;i++){
sb.append(elements[i] + ", ");
}
if(size > 0){
sb = new StringBuilder(sb.substring(0, sb.length() - 2));
}
sb.append("]");
return sb.toString();
}


/**
* 升序排列
* @param a
* @return
*/
public void insert(double a){
int index = this.getInsertIndex(a, 0, size-1);

if(size + 1 > elements.length){
int newCapacity = elements.length * 3 / 2 + 1;
double[] newElements = new double[newCapacity];
System.arraycopy(elements, 0, newElements, 0, index);

newElements[index] = a;
System.arraycopy(elements, index, newElements, index+1, size - index);

elements = newElements;
}else{
System.arraycopy(elements, index, elements, index+1, size - index);
elements[index] = a;
}
size++;
}

/**
* 升序排列
* @param a
* @param leftIndex
* @param rightIndex
* @return
*/
private int getInsertIndex(double a, int leftIndex, int rightIndex){
if(rightIndex < 0){//the first time
return leftIndex;
}
if(leftIndex == rightIndex){
if(a > elements[rightIndex]){
return rightIndex + 1;
}
return leftIndex;
}
int midIndex = (leftIndex + rightIndex) / 2;
if(a > elements[midIndex]){
return this.getInsertIndex(a, midIndex+1, rightIndex);
}else if(a < elements[midIndex]){
return this.getInsertIndex(a, leftIndex, midIndex-1);
}else{
return midIndex;
}
}

public void testInsert(){
this.insert(15);System.out.println(this);
this.insert(60);System.out.println(this);
this.insert(72);System.out.println(this);
this.insert(70);System.out.println(this);
this.insert(56);System.out.println(this);
this.insert(32);System.out.println(this);
this.insert(62);System.out.println(this);
this.insert(92);System.out.println(this);
this.insert(45);System.out.println(this);
this.insert(30);System.out.println(this);
this.insert(65);System.out.println(this);
}

public static void main(String[] args) {
Sort hs = new Sort ();
hs.testInsert();
}
}


//输出结果
/*
[15.0]
[15.0, 60.0]
[15.0, 60.0, 72.0]
[15.0, 60.0, 70.0, 72.0]
[15.0, 56.0, 60.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 62.0, 70.0, 72.0]
[15.0, 32.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 32.0, 45.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 30.0, 32.0, 45.0, 56.0, 60.0, 62.0, 70.0, 72.0, 92.0]
[15.0, 30.0, 32.0, 45.0, 56.0, 60.0, 62.0, 65.0, 70.0, 72.0, 92.0]
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值