package pandy.test.sort;
import java.util.Arrays;
/**
* @Author: Pandy
* @Date: 2019/2/13 20:21
* @Version 1.0
*/
public class Sort {
/**
* arr.length
* i-1 >=0
* arr[j+1] arr[j]
*插入排序 最好時間O(n) 平均時間O(n²) 最壞時間O(n²) 輔助空間O(1) 穩定
* @param arr
*/
public static void insertArray(Integer[] arr){
int temp = 0;
for (int i=0;i<arr.length;i++){
for (int j = i-1;j>=0;j--){
if (arr[j+1]>arr[j]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}else{
break;
}
}
}
}
/**
* 二分查詢法
* @param arr 測試陣列
* @param key 索引
* @param low 陣列低位
* @param high 陣列高位
*/
public static int recurisionBinarySearch(int arr[],int key,int low,int high){
if (key<arr[low]||key>arr[high]||low>high){
return -1;
}
int middle = (high + low)/2;
if (arr[middle]>key){
return recurisionBinarySearch(arr,key,low,middle-1);
}else if (arr[middle]<key){
return recurisionBinarySearch(arr,key,middle+1,high);
}else{
return middle;
}
}
/**
* 氣泡排序
* 前一個數字與後一個數字進行比較
* arr.length-1
* arr.length-1-i
* arr[j] arr[j+1]
*最好時間O(n) 平均時間O(n²) 最壞時間 O(n²) 輔助空間O(1) 穩定
*/
public static void bubbleSort(int[] arr){
int temp = 0;
for (int i =0;i<arr.length-1;i++){
for (int j =0;j<arr.length-1-i;j++){
if (arr[j]>arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
/**
* 希爾排序
*平均時間O(n 1.25次方 輔助空間O(1) 不穩定)
* @param
*/
public static void shellSort(int[] arr){
int num = arr.length/3+1;
while(num>0){
for (int i=0;i<arr.length;i++){
for (int j = i;j<arr.length-num;j=j+num){
if (arr[j]<arr[j+num]){
int temp = arr[j];
arr[j] = arr[j+num];
arr[j+num] = temp;
}
}
}
num = num/2;
}
}
/**
* 快速排序
* 最好時間O(nlgn) 平均時間O(nlgn) 最壞時間O(n²) 輔助空間O(lgn) 不穩定
* @param
*/
public static void fastSort(int[] arr,int low,int high){
int start = low;
int end = high;
int key = arr[low];
while(end>start){
while(end>start&&arr[end]>=key)
end--;
if (arr[end]<=key){
//交換
int temp = arr[end];
arr[end] = arr[start];
arr[start] = temp;
}
while(end>start&&arr[start]<=key)
start++;
if (arr[start]>=key){
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
if (start>low) fastSort(arr,low,start-1);
if (end<high) fastSort(arr,end+1,high);
}
}
/**
* 選擇排序
*最好時間O(n²) 平均時間O(n²) 最壞時間O(n²) 輔助空間O(1)
* @param
*/
public static void chooseSort(int[] arr){
for (int i=0;i<arr.length-1;i++){
int min = i;
for (int j = i+1;j<arr.length;j++){
if (arr[j]<arr[min]){
min = j;
}
}
if (min != i){
int temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
}
/**
*堆排序
* O(nlgn) 平均時間O(nlgn) 最壞時間O(nlgn) 不穩定
* @param
*/
public static void heapSort(int[] arr) {
//構造大根堆
heapInsert(arr);
int size = arr.length;
while(size>0) {
//固定最大值
swap(arr,0,size-1);
size--;
//構造大根堆
heapify(arr,0,size);
}
}
//構造大根堆通過新插入的數上升
public static void heapInsert(int[] arr) {
for(int i=0;i<arr.length;i++) {
//當前插入的索引
int currentIndex = i;
//父節點的索引
int fatherIndex = (currentIndex-1)/2;
//如果當前插入的值大於其父節點的值
//交換值 並將索引指向父節點
//然後繼續和上面的父節點進行比較 直到
//不大於父節點 則退出迴圈
while(arr[currentIndex]>arr[fatherIndex]) {
//交換當前節點與父節點的值
swap(arr,currentIndex,fatherIndex);
//將當前索引執行父索引
currentIndex = fatherIndex;
//重新計算當前索引的父索引
fatherIndex = (currentIndex-1)/2;
}
}
}
//將剩餘的數構造成大頂堆
public static void heapify(int[] arr,int index,int size) {
int left = 2*index+1;
int right = 2*index+2;
while(left<size) {
int largestIndex;
//判斷孩子中較大值的索引 要確保右孩子在size範圍內
if(arr[left]<arr[right]&&right<size) {
largestIndex = right;
}else {
largestIndex = left;
}
//比較父節點中的值與孩子中較大的值 並確定最大值得索引
if(arr[index]>arr[largestIndex]) {
largestIndex = index;
}
//如果父節點索引是最大值的索引 那已經是大根堆 退出迴圈
if(index==largestIndex) {
break;
}
//父節點不是最大值 與孩子中較大的值交換
swap(arr,largestIndex,index);
//將索引指向孩子中較大值得索引
index = largestIndex;
//重新計算交換後的孩子的索引
left = 2*index+1;
right = 2*index+2;
}
}
//交換陣列中兩個元素的值
public static void swap(int[] arr,int i,int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {
//Integer[] arr = {45,63,23,22,54,222,78,92,32,452,12,66,595};
int [] arr = {8,5,4,2,3,9,1,7,6};
//Sort.insertArray(arr);
//System.out.println(Arrays.toString(arr));
//int result = recurisionBinarySearch(arr1,3,0,arr1.length-1)+1;
//System.out.println(result);
//Sort.bubbleSort(arr);
//System.out.println(Arrays.toString(arr));
//Sort.shellSort(arr);
//System.out.println(Arrays.toString(arr));
//Sort.fastSort(arr,0,arr.length-1);
//System.out.println(Arrays.toString(arr));
//Sort.chooseSort(arr);
//System.out.println(Arrays.toString(arr));
Sort.heapSort(arr);
System.out.println(Arrays.toString(arr));
}
}