排序算法
1. 冒泡排序
每个相邻的位置都有可能会发生交换
public void sort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j <arr.length-1-i ; j++) {
if (arr[j]>arr[j+1]) ArrayUtils.swap(arr,j,j+1);
}
}
}
2. 选择排序
每次选择最小的元素放到前面 , 稳定性不确定,根据代码决定,是小于还是小于等于来决定
public void sort(int[] arr) {
for (int i = 0; i < arr.length; i++) {
for (int j = i+1; j <arr.length ; j++) {
int min=i;
if (arr[j]<arr[min]) min=j;
ArrayUtils.swap(arr,i,min);
}
}
}
3. 快整排序
是一个迭代的算法,每次找出不下bash, 将小于base的放到左边,大于base的放到右边。
public void sort(int[] arr, int start, int end) {
if (start > end) return;
System.out.println("当前的start==" + start + " 当前的end===" + end);
int mid = partiong(arr, start, end);
sort(arr, start, mid - 1);
sort(arr, mid + 1, end);
}
//划分函数
private int partiong(int[] arr, int low, int height) {
int pivot = arr[low];
int left = low;
int right = height;
while (left < right) {
while (left < right && pivot < arr[right]) {
right--;
}
arr[left] = arr[right];
while (left < right && pivot > arr[left]) {
left++;
}
arr[right] = arr[left];
}
arr[right] = pivot;
return right;
}
4. 堆排序
最重要的是如何维护堆的性质,一般用数组进行存储。
- 结点为i 的结点的父结点是(i-1)/2
- 结点为i的左结点是i*2+1
- 结点为i的右结点是i*2+1
//维持堆的性质
public void heapify(int[] arr, int i) {
int lagest = i;
int left = i * 2 + 1;
int right = i * 2 + 2;
if (i < arr.length && arr[lagest] < arr[left]) lagest = left;
if (i < arr.length && arr[lagest] < arr[right]) lagest = right;
if (lagest!=i){
//自己写的交换函数
ArrayUtils.swap(arr,lagest,i);
heapify(arr,lagest);
}
}
//建堆--使用的是维持堆的性质
//从第一个有孩子的结点开始
public void initHeap(int[] arr){
//建立一个大顶堆
for (int i = arr.length/2-1; i >=0 ; i--) {
heapify(arr, arr.length,i);
}
//进行堆排序
for (int i = arr.length-1; i >0 ; i--) {
ArrayUtils.swap(arr,i,0);
heapify(arr,i,0);
}
}