目录
堆排序
/** 构建最小堆 */
public static void MakeMinHeap(int a[], int n) {
for (int i = (n - 1) / 2; i >= 0; i--) {
MinHeapFixdown(a, i, n);
}
}
// 从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
public static void MinHeapFixdown(int a[], int i, int n) {
int j = 2 * i + 1; // 子节点
int temp = 0;
while (j < n) {
// 在左右子节点中寻找最小的
if (j + 1 < n && a[j + 1] < a[j]) {
j++;
}
if (a[i] <= a[j])
break;
// 较大节点下移
temp = a[i];
a[i] = a[j];
a[j] = temp;
i = j;
j = 2 * i + 1;
}
}
public static void MinHeap_Sort(int a[], int n) {
int temp = 0;
MakeMinHeap(a, n);
for (int i = n - 1; i > 0; i--) {
temp = a[0];
a[0] = a[i];
a[i] = temp;
MinHeapFixdown(a, 0, i);
}
}
归并排序:
* 归并排序的核心是两步:
* 1、把数组分割成左右子树,递归,直到不能在分割为止;
* 2、从最小子树 依次往上 逐层合并
public static void main(String[] args) {
int[] arr = {1,2,5,4,6,5,8,7};
int[] temp = new int[8];
print("【原始数组】", arr);
merge_sort(arr, 0, arr.length-1, temp);
print("【归并排序】", temp);
}
/**
* 递归 将数组分割成左右子树
* @param array
* @param first
* @param last
* @param temp
*/
public static void merge_sort(int array[], int first, int last, int temp[]) {
if (first < last) {
int middle = (first + last) / 2;
merge_sort(array, first, middle, temp);// 左半部分排好序
merge_sort(array, middle + 1, last, temp);// 右半部分排好序
mergeArray(array, first, middle, last, temp); // 合并左右部分
}
}
/**
* 合并 :将两个序列a[first-middle],a[middle+1-end]合并
* @param array 原始数组
* @param temp 临时存储排序成功的子数组,然后将子数组赋值给原始数组对应的部分
*/
public static void mergeArray(int array[], int first, int middle, int last, int temp[]) {
int begin = first; //子数组的起始索引
int point = middle; //子数组分割中点
int step = middle + 1; //子数组-右部分的起始点
int end = last; //子数组最后索引
int temp_index = 0; //定义 temp数组的index, 用于为temp数组赋值
while (begin <= point && step <= end) { //如果左子树和右子树都有元素 => 逐个比较添加进temp数组
if (array[begin] <= array[step]) {
temp[temp_index] = array[begin];
temp_index++;
begin++;
} else {
temp[temp_index] = array[step];
temp_index++;
step++;
}
}
while (begin <= point) { //左子树还没结束,右子树已经结束
temp[temp_index] = array[begin];
temp_index++;
begin++;
}
while (step <= end) { //右子树没结束, 左子树已经结束
temp[temp_index] = array[step];
temp_index++;
step++;
}
for (int ii = 0; ii < temp_index; ii++) {
array[first + ii] = temp[ii];
}
}
冒泡排序 ——> 快速排序:
快速排序——冒泡(交换)排序的改进——挖坑填空
随机取一个数作为key,将比key大的数放在右边,比key小的数放在左边
分成左右子数组 依次递归
public static void quickSort(int [] arr,int left,int right){
if(left>=right) {
return;
}
int key = arr[left]; //选择第一个数为key
int lIndex = left; //记录左移动的下标
int rIndex = right; //记录右移动的下标
while(lIndex < rIndex){
while(lIndex < rIndex && arr[rIndex] > key) { //从右向左 找小于key值 的索引
rIndex--;
}
if(lIndex < rIndex){
arr[lIndex] = arr[rIndex];
lIndex++;
}
while(lIndex < rIndex && arr[lIndex] < key) { //从左向右 找大于key值 的索引
lIndex++;
}
if(lIndex < rIndex){
arr[rIndex] = arr[lIndex];
rIndex--;
}
}
arr[lIndex] = key;
quickSort(arr, left, lIndex-1);//递归调用
quickSort(arr, lIndex+1, right);//递归调用
}
冒泡排序:
/**
* 冒泡排序
* 思想:两个数比较大小,较大的数下沉(往后),较小的数冒起来(往前)。
*/
方法一:
public static int[] BubbleSort(int [] arr){
int temp;//临时变量
boolean flag;//是否交换的标志
for(int i=0; i<arr.length-1; i++){ //表示趟数,一共arr.length-1次。
flag = false;
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;
flag = true;
}
}
if(!flag) {
break;
}
}
return arr;
}
方法二:
// 复杂度 0.5*n(n+1)
// 二次函数,
public static int [] sort(int array[]){
int cache;
for (int j = 0; j < array.length; j++) {
for (int i = 0; i < array.length-j; i++) {
if (i+1<array.length-j && array[i]>array[i+1]) {
cache = array[i+1];
array[i+1] = array[i];
array[i] = cache;
}
}
print(array);
}
return array;
}
public static void main(String[] args) {
int [] asd = {5,6,2,14,65,89,21,2,3};
int[] a = BubbleSort(asd);
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}