冒泡排序
比较相邻的两个数,把较大的往后排
每内循环一次将两个数较大的排在后面
每外循环一次将未排序的最大的数排在最后
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - i - 1; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
选择排序
每次内循环将未排序的第一个数与其后面所有的数依次比较,将小的放在前面
每次外循环可以排出最小的数放在最前
for (int i = 0; i < array.length - 1; 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;
}
}
}
频繁交换 array [ i ] 和被比较的数 array [ j ]
所以利用 minIndex 暂存内循环里最大的数的索引
内层循环完再和 array [ i ] 比较交换
for (int i = 0; i < array.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < array.length; j++) {
if (array[minIndex] > array[j]) {
minIndex = j;
}
}
if (array[i] != array[minIndex]) {
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
插入排序
从数组的第二个元素开始循环将数组中的元素插入
插入的数与当前位置的数向前递减依次比较
for (int i = 1; i < array.length; i++) {
for (int j = i; j > 0; j--) {
if (array[j] < array[j - 1]) {
int temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
}
}
}
同样交换次数频繁
for (int i = 1; i < array.length; i++) {
int insertNode = array[i];
int j = i - 1;
while (j >= 0 && insertNode < array[j]) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = insertNode;
}
快速排序
设第一个数为基准值,左右两个指针 i,j 向中间移动,j先动,j找到比基准值小的停下,i找到比基准值大的停下,两个交换,直到 i,j 相遇,这样基准值左边的都比他小,右边的都比他大;
基准值左右半部分继续使用这种思想排序
![归并排序](F:\非凡csdn\图片暂存\数据结构\数组排序\归并排序.gif)public int[] sort(int[] array) {
section(0, array.length - 1, array);
return array;
}
private void section(int left, int right, int[] arr) {
if (left > right) {
return;
}
int i = left;
int j = right;
int mark = arr[left];
while (i != j) {
while (arr[j] >= mark && i < j) {
j--;
}
while (arr[i] <= mark && i < j) {
i++;
}
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
arr[left] = arr[i];
arr[i] = mark;
section(left, j - 1, arr);
section(j + 1, right, arr);
}
归并排序
将数组不断分成相等的两部分,为每一个子序列排序,然后再合并成一个数组
public int[] sort(int[] array) {
mergeSort(0, array.length - 1, array);
return array;
}
private void mergeSort(int left, int right, int[] arr) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(left, mid, arr);
mergeSort(mid + 1, right, arr);
merge(left, mid, right, arr);
}
}
private void merge(int left, int mid, int right, int[] arr) {
int[] tempArr = new int[arr.length];
int i = left;
int j = mid + 1;
int k = left;
while (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
tempArr[k++] = arr[i++];
} else {
tempArr[k++] = arr[j++];
}
}
while (i <= mid) {
tempArr[k++] = arr[i++];
}
while (j <= right) {
tempArr[k++] = arr[j++];
}
for (int l = left; l <= right; l++) {
arr[l] = tempArr[l];
}
}
希尔排序
将待排数组按照一定的间隔分组,每组进行组内排序(插入排序)
组内间隔不断减小,直到减小为1
为什么不直接使用插入排序:减少交换次数
public void sort(int[] array) {
int d = array.length / 2;
while (d >= 1) {
insertSort(array, d);
d /= 2;
}
}
private void insertSort(int[] array, int d) {
for (int i = d; i < array.length; i++) {
int insertNode = array[i];
int j = i - d;
while (j >= 0 && insertNode < array[j]) {
array[j + d] = array[j];
j -= d;
}
array[j + d] = insertNode;
}
}
桶排序
把数组划分为大小想等的子区间(桶),桶可以用ArrayList,每个子区间去排序,最后合并
- 找出待排序数组中的最大值 max、最小值 min
- 创建桶,动态数组 ArrayList 作为桶,桶的数量为(max-min)/arr.length+1
- 遍历数组 arr,计算每个元素 array[i] 放的桶
- 每个桶各自排序
public void sort(int[] array) {
int max = 0;
int min = 0;
for (int i : array) {
max = Math.max(max, i);
min = Math.min(min, i);
}
int bucketNum = (max - min) / array.length + 1;
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketNum);
for (int i = 0; i < bucketNum; i++) {
bucketArr.add(new ArrayList<>());
}
for (int i : array) {
int num = (i - min) / array.length;
bucketArr.get(num).add(i);
}
for (ArrayList<Integer> integers : bucketArr) {
Collections.sort(integers);
}
int k = 0;
for (ArrayList<Integer> integers : bucketArr) {
for (Integer integer : integers) {
array[k] = integer;
k++;
}
}
}
基数排序
将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序
|