算法不光是要会写,更重要的是要理解记住它的思想
冒泡排序
外层循环是表示的内层循环需要对比的次数,内层循环每结束一次都会得出未排列出的部分的最大值 时间复杂度是O(n^2),空间复杂度是O(1),重要的是flag标志是在内层循环结束后会做一次判断,如果整个内层循环都未曾改变flag的值,说明数组已经是有序的
/**
* 冒泡排序
*
* @param a
*/
private void bubbleSort(int[] a) {
//选出最大的元素需要length-1次比较
for (int i = a.length - 1; i > 0; i--) {
boolean flag = false;
for (int j = 0; j < i; j++) {
if (a[j] > a[j + 1]) {
int tmp = a[j + 1];
a[j + 1] = a[j];
a[j] = tmp;
flag = true;
}
}
//没有交换说明已经成序
if (!flag)
break;
}
System.out.println("冒泡排序结果:" + Arrays.toString(a));
}
选择排序
/**
* 选择排序
*
* @param a
*/
private void selectSort(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
int min = i;
for (int j = i + 1; j < a.length; j++) {
if (a[min] > a[j])
min = j;
}
if (min != i) {
int tmp = a[min];
a[min] = a[i];
a[i] = tmp;
}
}
System.out.println("选择排序结果:" + Arrays.toString(a));
}
插入排序
/**
* 插入排序
*
* @param a
*/
private void insertSort(int[] a) {
for (int i = 1; i < a.length; i++) {
int j;
for (j = i - 1; j >= 0; j--) {
//找到第一个比a[i]小的索引
if (a[j] < a[i])
break;
}
if (j != i - 1) {
//每个元素向后移动一位
for (int k = i - 1; k > j; k--) {
a[k + 1] = a[k];
}
a[j + 1] = a[i];
}
}
System.out.println("插入排序结果:" + Arrays.toString(a));
}
桶排序
/**
* 桶排序
*
* @param a
*/
private void bucketSort(int[] a) {
int max = 0;
for (int i : a) {
if (i > max)
max = i;
}
//初始化水桶max+1个
int[] buckets = new int[max + 1];
for (int i = 0; i < a.length; i++) {
buckets[a[i]]++;
}
int index = 0;
for (int i = 0; i < buckets.length; i++) {
int key = buckets[i];
while (key-- > 0) {
a[index++] = i;
}
}
System.out.println("桶排序结果:" + Arrays.toString(a));
}
快速排序
/*************************快速排序*****************************/
private void quickSort(int[] a) {
quickSort(a, 0, a.length - 1);
System.out.println("快速排序结果:" + Arrays.toString(a));
}
private void quickSort(int[] a, int left, int right) {
if (left < right) {
int head = left;
int tail = right;
int x = a[head];
while (head < tail) {
while (head < tail && a[tail] > x)
tail--;
if (head < tail)
a[head++] = a[tail];
while (head < tail && a[head] > x)
head++;
if (head < tail)
a[tail--] = a[head];
}
a[head] = x;
quickSort(a, left, head - 1);
quickSort(a, head + 1, right);
}
}
堆排序
/****************************堆排序*****************************/
private void heapSort(int[] a) {
for (int i = a.length / 2 - 1; i >= 0; i--) {
maxHeapSort(a, i, a.length - 1);
}
for (int i = a.length - 1; i > 0; i--) {
//a[0]为最大元素,至于末尾
int tmp = a[0];
a[0] = a[i];
a[i] = tmp;
maxHeapSort(a, 0, i - 1);
}
System.out.println("堆排序结果:" + Arrays.toString(a));
}
/**
* 利用最大堆找出最大的元素
*
* @param a
* @param start
* @param end
*/
private void maxHeapSort(int[] a, int start, int end) {
int c = start;
//左孩子
int left;
int tmp = a[c];
for (left = 2 * c + 1; left <= end; c = left, left = 2 * left + 1) {
//选择左右孩子中较大的一个
if (left < end && a[left] < a[left + 1])
left++;
if (tmp >= a[left])
break;
else {
a[c] = a[left];
a[left] = tmp;
}
}
}
希尔排序
/**
* 希尔排序,用步长再插入
*
* @param a
*/
private void shellSort(int[] a) {
int n = a.length;
//步长每次除以2
for (int gap = n / 2; gap > 0; gap = gap / 2) {
//对每组进行插入排序
for (int i = 0; i < gap; i++) {
shellSort(a, i, gap);
}
}
System.out.println("希尔排序结果:" + Arrays.toString(a));
}
private void shellSort(int[] a, int start, int gap) {
//这里纯粹是一个插入排序
for (int j = start + gap; j < a.length; j = j + gap) {
int k;
for (k = j - gap; k >= start; k = k - gap) {
if (a[k] < a[j])
break;
}
if (k != j - gap) {
for (int i = j - gap; i > k; i = i - gap) {
a[i + 1] = a[i];
}
a[k + gap] = a[j];
}
}
}
基数排序
/***************************基数排序**************************/
private void radixSort(int[] a) {
int max = 0;
for (int i : a) {
if (max < i)
max = i;
}
for (int exp = 1; max / exp > 0; exp *= 10) {
radixSort(a, exp);
}
System.out.println("基数排序结果:" + Arrays.toString(a));
}
private void radixSort(int[] a, int exp) {
int[] output = new int[a.length];
int[] buckets = new int[10];
for (int i = 0; i < a.length; i++) {
buckets[(a[i] / exp) % 10]++;
}
for (int i = 1; i < 10; i++) {
buckets[i] += buckets[i - 1];
}
for (int i = a.length - 1; i >= 0; i--) {
int index = (a[i] / exp) % 10;
output[buckets[index] - 1] = a[i];
buckets[index]--;
}
for (int i = 0; i < output.length; i++) {
a[i] = output[i];
}
}
归并排序
/**************************归并排序***************************/
private void mergeSort(int[] a) {
mergeSort(a, 0, a.length - 1);
System.out.println("归并排序结果:" + Arrays.toString(a));
}
private void mergeSort(int[] a, int start, int end) {
if (start < end) {
int mid = (end + start) / 2;
mergeSort(a, start, mid);
mergeSort(a, mid + 1, end);
merge(a, start, mid, end);
}
}
private void merge(int[] a, int start, int mid, int end) {
int[] output = new int[end - start + 1];
int index = 0;
int i = start;
int j = mid + 1;
while (i <= mid && j <= end) {
if (a[i] < a[j])
output[index++] = a[i++];
if (a[j] < a[i])
output[index++] = a[j++];
while (i <= mid) {
output[index++] = a[i++];
}
while (j <= end) {
output[index++] = a[j++];
}
}
for (int k = 0; k < output.length; k++) {
a[start + k] = output[k];
}
}
计数排序
/**
* 计数排序
*
* @param a
*/
private void countSort(int[] a) {
//找出最大值和最小值
int min = a[0], max = a[0];
for (int i : a) {
if (min > i)
min = i;
if (max < i)
max = i;
}
//初始化桶
int[] buckets = new int[max - min + 1];
for (int i = 0; i < a.length; i++) {
buckets[a[i] - min]++;
}
//这里和基数排序一样
for (int i = 1; i < max - min + 1; i++) {
buckets[i] += buckets[i - 1];
}
int[] output = new int[a.length];
for (int i = a.length - 1; i >= 0; i--) {
output[buckets[a[i] - min] - 1] = a[i];
buckets[a[i] - min]--;
}
for (int i = 0; i < output.length; i++) {
a[i] = output[i];
}
System.out.println("计数排序结果:" + Arrays.toString(a));
}
测试用例
private static final int[] SORT_ARRAY = {43, 64, 21, 6565, 3424, 22, 6523, 345, 89, 68, 162, 528};
public static void main(String[] args) {
Sort sort = new Sort();
sort.bubbleSort(SORT_ARRAY);
sort.selectSort(SORT_ARRAY);
sort.insertSort(SORT_ARRAY);
sort.bucketSort(SORT_ARRAY);
sort.quickSort(SORT_ARRAY);
sort.heapSort(SORT_ARRAY);
sort.shellSort(SORT_ARRAY);
sort.radixSort(SORT_ARRAY);
sort.mergeSort(SORT_ARRAY);
sort.countSort(SORT_ARRAY);
}
测试结果
冒泡排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
选择排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
插入排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
桶排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
快速排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
堆排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
希尔排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
基数排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
归并排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]
计数排序结果:[21, 22, 43, 64, 68, 89, 162, 345, 528, 3424, 6523, 6565]