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

JAVA中的几个排序算法

2015-08-06 22:22 363 查看
今天是我第一天来写JAVA的博客,有不足的地方大家多多包涵

下面的代码是 一些我自己整理出来的排序算法 请多指教咯

package sortMethods;

public class sortMethods {
private static void print(int[] a) {
for (int b : a) {
System.out.print(b + " ");
}
}

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

}

public static void main(String[] args) {
int a[] = { 0, 21, 8, 13, 25, 5, 49, 25, 16, 8 };
// int[] a = { 5, 4 };
// 冒泡排序1
// bubbling(a);

// 冒泡排序优化2
// bubbling2(a);

// 选择排序
// select(a);

// 3插入排序-1
// inset(a);

// 3-2二分法
// binarySort(a);

// 4 希尔排序
// shellSort(a);

// 5 快速排序
// quickSort(a, 0, a.length - 1);

// 6归并
mergeSort(a, 0, a.length - 1);

print(a);
}

private static void mergeSort(int[] a, int left, int right) {
if (left < right) {// 至少有2个元素
int mid = (left + right) / 2; // 二分,取中点
// 把序列拆分成两个子序列:[left,mid] 和 [mid+1,right]
// 同时还要对分解后的子序列分别进行递归“归并排序”
mergeSort(a, left, mid);
mergeSort(a, mid + 1, right);

// 把前面两个已经排好序的子序列进行归并
int b[] = new int[a.length];
merge(a, b, left, mid, right);
copyArray(a, b, left, right);
}
}

private static void copyArray(int[] a, int[] b, int left, int right) {
for (int i = left; i <= right; i++) {
a[i] = b[i];
}
}

// 把两个已经排好序的子序列(a[left,mid]和a[mid+1,right]) 合并成一个 ( b[left,right] )
private static void merge(int[] a, int[] b, int left, int mid, int right) {
int p = left;
int r = mid + 1;
int k = left;
while (p <= mid && r <= right) {
if (a[p] <= a[r]) {
b[k++] = a[p++];
} else {
b[k++] = a[r++];
}
}
// 此时,肯定有一个子序列中的元素全部移到b[]数组,因此,只要把还未移完的子序列当中的所有剩余元素直接对拷到数组b[]当中即可
if (p > mid) {// 左子序列已经完成。因此剩下的是右序列,对拷右序列当中的剩余元素即可
for (int i = r; i <= right; i++) {
b[k++] = a[i];
}
} else {// 对拷左子序列中的剩余元素
for (int i = p; i <= mid; i++) {
b[k++] = a[i];
}
}
}

// 5 快速排序
private static void quickSort(int[] a, int p, int r) {
if (p < r) {
// 把数组划分成两个子数组和一个元素(枢轴):
// 用枢轴a[q]把整数数组划分成 ==> a[p,q-1] , a[q] , a[q+1,r]
int q = partition(a, p, r); // a[q]
quickSort(a, p, q - 1);// 排左边的子数组a[p,q-1]
quickSort(a, q + 1, r);// 排右边的子数组a[q+1,r]
}

}

private static int partition(int[] a, int p, int r) {
// 優化代碼//优化:采用随机选择策略确定枢轴----随机选取数组当中的一个元素,和第一个元素进行交换。之后,以第一个元素作为枢轴进行划分
int rand = (int) (Math.random() * (r - p));
swap(a, p, p + rand);

int i = p;// 第一个元素定为枢轴
int j = r + 1;
int x = a[p];

while (true) {
while (a[++i] < x && i < r)
;// 定位指针i,找比x大的元素 <--为的是找要交换到右边的"非法"元素
while (a[--j] > x)
;// 定位指针j <--为的是找要交换到左边的"非法"元素
if (i >= j) {
break;
}
swap(a, i, j);
}
swap(a, p, j);// 枢轴a[p]要换到中间位置
return j;
}

// 4 希尔排序
private static void shellSort(int[] a) {
// 进行分组,初始步长设为数组长度的一半即n/2,然后依次减半,直到最后取1
for (int gap = (a.length + 1) / 2; gap > 0;) {
// 组内排序
for (int i = 0; i < a.length - gap; i++) {
for (int j = i; j < a.length - gap; j += gap) {
if (a[j] > a[j + gap]) {// 定位到每一个元素
swap(a, j, j + gap);
}
}
}
// for循环的修正
if (gap > 1) {
gap = (gap + 1) / 2;
} else if (gap == 1) {
break;
}

}

}

// 3-2二分法
private static void binarySort(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
int temp = a[i + 1];
int low = 0;
int high = i;
int mid;
// 在low与 high之间的区域内进行二分查找,以确定新元素的插入位置
while (low <= high) {
mid = (high + low) / 2;
if (a[mid] > temp) {// 若待插入的数小于中间元素a[mid],则目标落于左半区
high = mid - 1;
} else {// 若待插入的数大于等于中间元素a[mid],则目标落于右半区
low = mid + 1;
}
}
// 搜索的最后一个小区间的high位置即是查找目标,因此新元素的插入位置即是high+1
// 把原来从high到i范围内的元素依次往后移一个位置
for (int j = i; j > high; j--) {
a[j + 1] = a[j];
}
a[high + 1] = temp;// 无论如何都是插入到high+1位置,可以推导的
}

}

private static void inset(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
int temp = a[i + 1];
int j = i;
// 插入第i个数
// 从后往前搜,发现a[j]>temp时,则把a[j]后移到j+1的位置,继续往前搜。
while (a[j] > temp) {
a[j + 1] = a[j];
a[j] = temp;
j--;
if (j < 0) {
break;
}
}
// 否则即a[j]<=temp时,直接把待插入的数放到a[j+1]处
a[j + 1] = temp;
}
}

private static void select(int[] a) {
// 关键在于标签
for (int i = 0; i < a.length - 1; i++) {
int j, k;
for (j = i + 1, k = i; j < a.length; j++) {
if (a[j] < a[k]) {
k = j;
}
}
if (a[i] != a[k]) {
swap(a, i, k);
}
}
}

// 如果已经是拍好序了 就不用再排序了
private static void bubbling2(int[] a) {
boolean flag = false;
for (int i = 0; i < a.length - 1; i++) {
flag = true;// 标志
for (int j = 0; j < a.length - 1 - i; j++) {
if (a[j] > a[j + 1]) {
swap(a, j, j + 1);// 排序
flag = false;// 如果进入if语句说明前面假设不成立
}
}
if (flag) {// 如果为true则返回函数
return;
}
}
}

private static void bubbling(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
swap(a, j, j + 1);// 排序
}
}
}
}

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