- 冒泡排序
冒泡排序会走过每一个数字,如果前后相邻的两个数字大小顺序与要求不相同则调转位置,直至相邻的数字大小顺序与要求相符合。
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
sort (a);
}
public static void sort (int[] a) {
int temp;
for (int j = 0; j < a.length; j++) {
for (int i = 0; i < a.length - 1 - j; i++) {
if (a[i] > a[i + 1]) {
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
}
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
}
- 选择排序
每一次循环都会将数组中最大(或最小)的一个放在末端,它的位置不会再改变。下一次循环对剩下的数字进行重复的操作,直至排序结束。
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
sort (a);
}
public static void sort (int[] a) {
int length = a.length;
int min;//最小数字的位置
int temp;
for (int i = 0; i < length; i++) {
min = i;//假定i为最小数字的脚标
for (int j = i + 1; j < length; j++) {
if (a[j] < a[min])
min = j;//如果脚标j对应的数值小于当前最小值,则最小值的脚标为j
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
}
- 快速排序
快速排序是找到一个数组中的一个作为“基准”,再将数组中小于(大于)“基准”的数放在它前面(后面),比“基准”大(小)的则反之。
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
quickSort (a);
}
public static void sort (int[] a, int low, int high) {
int i, j, index;
if (low > high)
return;//递归的出口
i = low;
j = high;
index = a[low];//用第一个数做基准
//从两端开始向中间进行扫描
while (i < j) {
while (i < j && a[j] >= index)
j--;//从右边开始找到第一个比基准小的数
while (i < j && a[i] < index)
i++;//从左边开始找到第一个比基准大的数
//交换两个数
if (i < j) {
int p = a[i];
a[i] = a[j];
a[j] = p;
}
//将基准放在小于它与大于它的数之间
int p = a[i];
a[i] = a[low];
a[low] = p;
}
//对基准左右两侧的数组进行操作
sort(a, low, i - 1);
sort(a, i + 1, high);
}
public static void quickSort (int[] a) {
if (a.length > 0)
sort(a, 0, a.length - 1);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}
- 插入排序
插入排序,从数组的第一个数开始看作已经排序好,并开始对数组进行扫描,将数与已经排序好的部分进行比较,插进合适的位置,直至所有数都被扫描完毕。
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
sort (a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public static void sort (int[] a) {
int length = a.length;
int temp;
for (int i = 1; i < length; i++) {
//j从i位置开始,向右边扫描,若左边数比右边大,则交换位置直至到j - 1 = 0
for (int j = i; j > 0 && a[j - 1] > a[j]; j--) {
temp = a[j];
a[j] = a[j - 1];
a[j - 1] =temp;
}
}
}
}
- 归并排序
归并排序的精髓在于先将数组分解成最小单位,再在组合的过程中进行排序,这样当数组再次完整时,顺序也已经被排好了。
主要过程如下:
- 分解
- 治理
- 合并
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
sort (a, 0, a.length - 1);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public static void sort (int[] a, int low, int high) {
int middle = (low + high) / 2;
if (low < high) {
sort(a, low, middle);
sort(a, middle + 1, high);//分解
//合并
merge (a, low, middle, high);
}
}
public static void merge (int[] a, int low, int middle, int high) {
int[] temp = new int[high - low + 1];//定义一个当前长度的数组(1~3是3个数,故是high-low+1)
int i = low;
int j = middle + 1;
int k = 0;
//找到较小的数
while (i <= middle && j <= high) {
if (a[i] < a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
//把左边数组的数填进新数组
while (i <= middle)
temp[k++] = a[i++];
//把右边数组的数填进新数组
while (j <= high)
temp[k++] = a[j++];
//将排好序的数组填进原始数组相应位置
for (int l = 0; l < temp.length; l++) {
a[l + low] = temp[l];
}
}
}
- 堆排序
通过建立大顶堆或是小顶堆来对数组进行排序
需要知道在堆中i节点的左右孩子节点与其关系为i * 2 + 1和i * 2 + 2
i节点不能大于其左右孩子节点的值,若大于,则交换
主要过程如下:
交换根节点的数与数组最后一个数,从根节点开始进行节点与其左右孩子节点的比较
重复以上步骤直至全部交换比较完毕
代码如下:
public class Test {
public static void main (String[] args) {
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
a[i] = (int) (Math.random() * 100);
sort (a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
public static void sort(int[] array) {
if (array == null || array.length == 1)
return;
buildMaxHeap(array); // 第一次排序,构建最大堆,只保证了堆顶元素是数组里最大的
for (int i = array.length - 1; i >= 1; i--) {
// 这个是什么意思呢?,经过上面的一些列操作,目前array[0]是当前数组里最大的元素,需要和末尾的元素交换
// 然后,拿出最大的元素
swap(array, 0, i);
// 交换完后,下次遍历的时候,就应该跳过最后一个元素,也就是最大的那个值,然后开始重新构建最大堆
// 堆的大小就减去1,然后从0的位置开始最大堆
maxHeap(array, i, 0);
}
}
// 构建堆
public static void buildMaxHeap(int[] array) {
if (array == null || array.length == 1)
return;
// 堆的公式就是 int root = 2*i, int left = 2*i+1, int right = 2*i+2;
int cursor = array.length / 2;
for (int i = cursor; i >= 0; i--) { // 这样for循环下,就可以第一次排序完成
maxHeap(array, array.length, i);
}
}
// 最大堆
public static void maxHeap(int[] array, int heapSieze, int index) {
int left = index * 2 + 1; // 左子节点
int right = index * 2 + 2; // 右子节点
int maxValue = index; // 暂时定在Index的位置就是最大值
//如果左子节点的值,比当前最大的值大,就把最大值的位置换成左子节点的位置
if (left < heapSieze && array[left] > array[maxValue]) {
maxValue = left;
}
//如果右子节点的值,比当前最大的值大,就把最大值的位置换成右子节点的位置
if (right < heapSieze && array[right] > array[maxValue]) {
maxValue = right;
}
//如果不相等,说明这个子节点的值有比自己大的,位置发生了交换
if (maxValue != index) {
swap(array, index, maxValue); // 就要交换位置元素
//继续进行排序
maxHeap(array, heapSieze, maxValue);
}
}
// 数组元素交换
public static void swap(int[] array, int index1, int index2) {
int temp = array[index1];
array[index1] = array[index2];
array[index2] = temp;
}
}