/**
* @author suchuner
* @className SortAlgorithm
* @description TODO
* @date 2018-09-11 12:03
*/
public class SortAlgorithm {
private SortAlgorithm() {
}
public static void main(String[] args) {
int[] arr= {-11,100,2,3,1,100,100,45,101,6,9,7,-1,5};
// bubbleSort(arr);
// insertSort(arr);
// selectSort(arr);
quickSort(arr);
// System.out.println(Arrays.toString(arr));
System.out.println(binnarySearch(arr,101));
}
public static void quickSort(int[] arr){
quickSort(arr,0,arr.length-1);
}
/**实现思路:
* 1.快速查询的思想:
* 一个待排序的数组,设置左右哨兵和假定数组第一个位置为基数位置,
* 右哨兵先开始向左查找比基数小的数,并在这个数的位置停下;
* 左哨兵开始向右查找比基数大的数,并在这个数的位置停下;
* 当左右哨兵还未相遇,在两者停下的位置,交换位置上的值。
* 当左右哨兵相遇,交换基数与相遇位置的值。
* 左右分割继续执行以上步骤。
*
* @param arr
* @param low
* @param high
*/
public static void quickSort(int[] arr,int low,int high){
if(low<high) {//防止递归时,栈溢出
int i = low, j = high, flag = arr[low];
while (i<j){//如果左右哨兵还未相遇,则继续执行与基数的比较
//从右往左查询,查询到比基数小的位置停止,如果没有i<j的条件时,基数已经为最小值时,右哨兵越界 等于条件是保证稳定性
while (flag<=arr[j]&&i<j) j--;
//从左往右查询,查询到比基数大的位置停止,如果没有i<j的条件时,基数已经为最大值时,左哨兵越界 等于条件是保证稳定性
while (flag>=arr[i]&&i<j) i++;
//当左右哨兵都停止时,且左哨兵在右哨兵的左方,交换这两个位置的值
if(i<j) changePlace(arr,i,j);
}
//左右哨兵相遇,将基数与相遇位置的值交换。
arr[low]=arr[i];
arr[i]=flag;
//分割执行 左递归
quickSort(arr,low,i-1);
//分割执行,右递归
quickSort(arr,i+1,high);
}
}
/**实现思路:
* 1.选择排序的思想:
* 一个待排序的数组,依次比较,寻找数组中最小值的索引位置。
*(第一轮比较)假定索引0位置的值为最小值,则该位置的与后面位置的值依次比较,找到最小值的索引位置。
* 将找到的最小值的与最初假定最小值进行交换
* 由于索引0的位置已经为最小值了,则开始找第二小的值。
* (第二轮比较)假定索引1位置的值为最小值,
* ...
*
* @param arr
*/
public static void selectSort(int[] arr){
for (int i = 0; i <arr.length-1 ; i++) {
int minIndex = i;//每次循环都假定i位置为最小值
for (int j = i+1; j < arr.length; j++) {//从后一个位置开始循环,寻找最小值
if(arr[minIndex]>arr[j]){//如果找到比上一个小的值,将该值的索引位置赋值给最小索引
minIndex=j;
}
}
//用于比较的循环结束,找到了最小值的索引位置(最初位置已经为最小时,就不必交换位置的值了)
if(i!=minIndex) changePlace(arr,i,minIndex);
}
}
/**实现思路:
* 1.直接插入排序思想:
* 一个待排序的数组,锁定索引0位置。取下一个的索引位置的值与前面的值进行比较
* 一直往前比较,如果前面的值比该值大,则交换位置。否则,位置确定。
* 继续取下一个索引位置的值与前面的值比较
* ...
* @param arr
*/
public static void insertSort(int[] arr){
for (int i = 1; i < arr.length; i++) {
for (int j = i; j >0 ; j--) {
if(arr[j]<arr[j-1]){
changePlace(arr,j-1,j);
}else{
break;
}
}
}
}
/**实现思路:
* 1.冒泡查询思想:
* @param arr
*/
public static void bubbleSort(int[] arr){
int count =0;
for (int i = 0; i <arr.length ; i++) {
for (int j = 0; j <arr.length-count-1 ; j++) {
if(arr[j]>arr[j+1]){
changePlace(arr,j,j+1);
}
}
count++;
}
}
public static int binnarySearch(int[] arr,int value){
return binnarySearch(arr,0,arr.length-1,value);
}
/**
* 书写二分查找法注意点:
* 注意:
* 1.二分查找法的基本实现的方法有四个参数
* a.数组 最低索引值(0) 最高索引值(数组长度-1:why?当对半取值时取到high时会造成索引越界异常) 待查找的元素
* 2.对半算法可以在循环的内部,也可以在循环的外部(放在内部可以在满足条件时在计算对半值,少些计算)
* 3.使用递归时,方法有返回值时 必须加return语句
* 4.循环判断的条件必须有等于(=) why? 当取到第一个或者最后一个时,如果没有等于号(=)无法取到值
*
* @param arr
* @param low
* @param high
* @param value
* @return
*/
public static int binnarySearch(int[] arr,int low,int high,int value){
if(low<=high){
int midIndex = (low+high)>>1;
int midVal = arr[midIndex];
if(midVal<value){
return binnarySearch(arr,midIndex+1,high,value);
}else if(midVal>value){
return binnarySearch(arr,low,midIndex-1,value);
}else{
return midIndex;
}
}
return -1;
}
public static void changePlace(int[] arr,int i,int j){
int temp = arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
07-30