初级篇:三个O(n^2)的排序算法
仅记录代码实现和大概思路。
一、冒泡
思路:内层循环每次都从后面开始,外层从前面开始。内层每次都会找到一个小的数,放在数组的最前面。因此内层循环i次就完成了排序。
public void BubbleSort(int[] arr){
int temp=0;//临时变量
for(int i=0; i<arr.length-1; i++){ //表示趟数,一共arr.length-1次。
for(int j=arr.length-1; j>i; j--){
if(arr[j] < arr[j-1]){
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
}
}
二、选择排序
以如下代码为例,选择排序就是,每次都找到未排序的最小的元素,用一个变量记录这个元素索引,然后将该元素和未排序的部分的首位元素交换,可以看到交换次数只有n次。
public static void select_sort(int array[]){
for(int i=0;i<array.length-1;i++){
int minIndex = i;
for(int j=i+1;j<array.length;j++){
if(array[j]<array[minIndex]){
minIndex = j;
}
}
if(minIndex != i){
int temp = array[i];
array[i] = array[minIndex];
array[minIndex] = temp;
}
}
}
三、插入排序
类似于打扑克牌的时候,让摸到的手牌一直有序。
public static void insert_sort(int array[]){
int temp = array[0];
for(int i=0;i<array.length-1;i++){
for(int j=i+1;j>0;j--){
if(array[j] < array[j-1]){
temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}else{ //不需要交换 提前退出是优化
break;
}
}
}
}高级篇:三个O(nlogn)的排序算法
四、归并排序
public class MergeSort {
public void MergeSort(int[] arr) {
MergeSort(arr,0,arr.length-1);
}
private void MergeSort(int[] arr, int left, int right) {
// 如果 left == right,表示数组只有一个元素,则不用递归排序
if (left < right) {
// 把大的数组分隔成两个数组
int mid = (left + right) / 2;
// 对左半部分进行排序
MergeSort(arr, left, mid);
// 对右半部分进行排序
MergeSort(arr, mid + 1, right);
//进行合并
merge(arr, left, mid, right);
}
}
private void merge(int[] arr, int left, int mid, int right) {
//先用一个临时数组把他们合并汇总起来
int[] array = new int[right - left + 1];
int i = left;//左半部分起始索引
int j = mid + 1;//右半部份起始索引
int k = 0;
while (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
array[k++] = arr[i++];
} else {
array[k++] = arr[j++];
}
}
while(i <= mid)
array[k++] = arr[i++];
while(j <= right)
array[k++] = arr[j++];
// 把临时数组复制到原数组
for (i = 0; i < k; i++) {
arr[left] = array[i];
left++;
}
}
}五、快速排序
快速排序有三个版本,下列为初级版本,版本2应该是使用随机数,版本3是三路快排,可以理解成分成三个部分,左边是小于,中间是等于,右边是大于。(暂时收录基本写法)
public class QuickSort {
public static void quickSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
public static void quickSort(int n[], int left, int right) {
int dp;
if (left < right) {
dp = partition(n, left, right);//先找一个数,然后分成两边处理
quickSort(n, left, dp - 1);
quickSort(n, dp + 1, right);
}
}
//partiton是最核心的部分,目的是对于某个数a,其左边都是小于a,右边都是大于a。
public static int partition(int n[], int left, int right) {
int pivot = n[left];//这里选择的是最左侧,也是最基础的写法,这里使用随机数可以优化
while (left < right) {
while (left < right && n[right] >= pivot)
right--;
if (left < right) {
n[left] = n[right];
left++;
}
while (left < right && n[left] <= pivot)
left++;
if (left < right) {
n[right] = n[left];
right--;
}
}
n[left] = pivot;
return left;
}
}
六、堆排序
堆排序的一个细节是,如果给定的是一个接一个的数据,那么慢慢插入,如果是给定了一个数组过来,则最好直接heapify调整。对应本示例的downAdjust方法。
大顶堆:每个结点的值都大于或等于其左右孩子结点的值
小顶堆:每个结点的值都小于或等于其左右孩子结点的值
public class HeapSort {
// 堆排序
public static int[] heapSort(int[] arr) {
int n = arr.length;
//构建大顶堆
for (int i = (n - 2) / 2; i >= 0; i--) {
downAdjust(arr, i, n - 1);
}
//进行堆排序
for (int i = n - 1; i >= 1; i--) {
// 把堆顶元素与最后一个元素交换
int temp = arr[i];
arr[i] = arr[0];
arr[0] = temp;
// 把打乱的堆进行调整,恢复堆的特性
downAdjust(arr, 0, i - 1);
}
return arr;
}
//下沉操作。在parent到n这个区间,parent这个位置的数不对。
public static void downAdjust(int[] arr, int parent, int n) {
//临时保存要下沉的元素
int temp = arr[parent];
//定位左孩子节点的位置
int child = 2 * parent + 1;
//开始下沉
while (child <= n) {
// 如果右孩子节点比左孩子大,则定位到右孩子
if(child + 1 <= n && arr[child] < arr[child + 1])
child++;
// 如果孩子节点小于或等于父节点,则下沉结束
if (arr[child] <= temp ) break;
// 父节点进行下沉
arr[parent] = arr[child];
parent = child;
child = 2 * parent + 1;
}
arr[parent] = temp;
}
}二分查找法
public class Find {
public int binarysearch(int a[], int key) {
int low = 0;
int high = a.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (a[mid] > key)
high = mid - 1;
else if (a[mid] < key)
low = mid + 1;
else if (a[mid] == key)
return mid;
}
return -1;
}
}又或者是
public class Find {
public int binarysearch(int a[], int key) {
int low = 0;
int high = a.length ;//两个写法的边界是不同的
while (low < high) {
int mid = low + (high - low) / 2;
if (a[mid] > key)
high = mid ;
else if (a[mid] < key)
low = mid + 1;
else if (a[mid] == key)
return mid;
}
return -1;
}
}


京公网安备 11010502036488号