* 快速排序:
* 算法思想:基于分治的思想,是冒泡排序的改进型。
* 首先在数组中找到一个基准点(基准点的选择可能会影响快速排序的效率,在补充处)
* 然后分别从数组的两端扫描数组,设两个指标(lo指向起始位置,hi指向末尾),
* 首先从后半部分开始,若果发现有比基准点小的,就交换lo和hi的值,
* 然后再从前半段开始扫描,发现有比基准点大的,就交换lo和hi的值,
* 如此往复循环,直到lo>=hi,然后把基准点的值放到hi这个位置
* 一次排序就完成了
* 接下来采用递归的方式分别对前半部分和后半部分排序,当前半部分有序、后半段有序,整个数组就自然有序列
* 快速排序的时间复杂度是O(NlogN)
*
* 【补充】:基准点的选取
* https://www.cnblogs.com/y3w3l/p/6444837.html
* https://blog.csdn.net/liuyi1207164339/article/details/50827608
package Test;
import java.util.ArrayList;
import java.util.Scanner;
public class No11_quickSort {
/*
* 快速排序:
* 算法思想:基于分治的思想,是冒泡排序的改进型。
* 首先在数组中找到一个基准点(基准点的选择可能会影响快速排序的效率,在补充处)
* 然后分别从数组的两端扫描数组,设两个指标(lo指向起始位置,hi指向末尾),
* 首先从后半部分开始,若果发现有比基准点小的,就交换lo和hi的值,
* 然后再从前半段开始扫描,发现有比基准点大的,就交换lo和hi的值,
* 如此往复循环,直到lo>=hi,然后把基准点的值放到hi这个位置
* 一次排序就完成了
* 接下来采用递归的方式分别对前半部分和后半部分排序,当前半部分有序、后半段有序,整个数组就自然有序列
* 快速排序的时间复杂度是O(NlogN)
*
* 【补充】:基准点的选取
* https://www.cnblogs.com/y3w3l/p/6444837.html
* https://blog.csdn.net/liuyi1207164339/article/details/50827608
*
*
* */
static int[] array = new int[8];
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
System.out.println("请向数组输入8个整数:");
for(int i=0;i<8;i++) {
array[i] = in.nextInt();
}
System.out.println("输出快速排序的结果:");
sort(array,0,7);
for(int i=0;i<8;i++) {
System.out.println(array[i]+" ");
}
}
public static int partition(int[] array,int lo,int hi) {
if(lo>=hi) {
return -1;
}
//基准数选取为lo位置,固定的切分方式
int key = array[lo];
while(lo<hi) {
while(array[hi]>=key&&lo<hi) {
hi--;
}
//将hi的值付给了lo 造成了hi为空(并非真的没有值,而是没有再进行赋值的意思)
array[lo]=array[hi];
while(array[lo]<=key&&lo<hi) {
lo++;
}
//将lo的值赋给hi 造成了lo为空
array[hi]=array[lo];
}
array[hi] = key; //此时hi = lo,所以赋给hi或者lo都可以
return hi;
}
public static void sort(int[] array,int lo,int hi) {
if(lo>=hi) {
return;
}
int index = partition(array,lo,hi);
sort(array,lo,index-1);
sort(array,index+1,hi);
}
}
* 面试题11:旋转数组的最小数字
* 题目:把一个数组最开的的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个递增排序的数组的一个旋转,输出旋转数组的 最小元素。
* 例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个选装,该数组的最小值为1.
*
*
* 思路:利用二分法,设置两个指针,第一个变量指向第一个元素,第二个变量指向最后一个元素
* 找到中间的数,首先和第一个变量进行对比,若是比第一个变量大,则中间元素属于前半部分数组,将第一个元素的指向移到中间位置
* 然后和第二个变量进行对比,若是比第二个变量小,则中间元素属于后半部分数组,将第二个元素的指向移到中间位置
* 查找范围缩小一半,再进行新一轮的查找。。。
* 直到第一个指向前半部分数组的最后一个,第二个指向后半数组的第一个,也就是两者相邻
* 第二个指向的就是最小的元素
*
* 其中根据旋转数组的定义还有一个特例,也就是将排序数组的前面0个元素搬到最后去,
* 也就是排序数组本身,这仍然是数组的一个旋转,也就是第一个数字大于最后一个数字时,直接返回第一个数字就可
* 若是左中右三值相等时,又该如何呢,前面的思路不能支持这种情况,
* 所以原来的方法不可行,
* 例如:1,0,1,1,1与1,1,1,0,1情况
* 这里我们采用顺序查找的方式进行 其他还有不是用这种解决的
详见https://blog.csdn.net/baiye_xing/article/details/78428318 中的第8个
package Test;
import java.util.Scanner;
public class No11min {
/*
* 面试题11:旋转数组的最小数字
* 题目:把一个数组最开的的若干个元素搬到数组的末尾,我们称之为数组的旋转。
* 输入一个递增排序的数组的一个旋转,输出旋转数组的 最小元素。
* 例如:数组{3,4,5,1,2}为{1,2,3,4,5}的一个选装,该数组的最小值为1.
*
*
* 思路:利用二分法,设置两个指针,第一个变量指向第一个元素,第二个变量指向最后一个元素
* 找到中间的数,首先和第一个变量进行对比,若是比第一个变量大,则中间元素属于前半部分数组,将第一个元素的指向移到中间位置
* 然后和第二个变量进行对比,若是比第二个变量小,则中间元素属于后半部分数组,将第二个元素的指向移到中间位置
* 查找范围缩小一半,再进行新一轮的查找。。。
* 直到第一个指向前半部分数组的最后一个,第二个指向后半数组的第一个,也就是两者相邻
* 第二个指向的就是最小的元素
*
* 其中根据旋转数组的定义还有一个特例,也就是将排序数组的前面0个元素搬到最后去,
* 也就是排序数组本身,这仍然是数组的一个旋转,也就是第一个数字大于最后一个数字时,直接返回第一个数字就可
* 若是左中右三值相等时,又该如何呢,前面的思路不能支持这种情况,
* 所以原来的方法不可行,
* 例如:1,0,1,1,1与1,1,1,0,1情况
* 这里我们采用顺序查找的方式进行
*
*
* */
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = new int[5];
Scanner in = new Scanner(System.in);
System.out.println("输如一个长度为5的数组:");
for(int i=0;i<5;i++) {
array[i]=in.nextInt();
}
System.out.println("利用旋转数组的特性,输出数组中最小的元素"+min(array));
}
private static int min(int[] array) {
// TODO Auto-generated method stub
if(array==null||array.length==0) {
return 0;
}
int left = 0;
int right =array.length-1;
//若是旋转0位,则将array[0]的值返回即可
int min = array[left];
while(array[left] >= array[right]) {
if(right-left<=1) {
min = array[right];
break;
}
int mid = (left+right)/2;
if(array[mid]==array[left]&&array[mid]==array[right]) {
min = minInOrder(array,left,right);
break;
}
else if(array[mid]>=array[left]) {
left = mid;
}
else if(array[mid]<=array[right]) {
right = mid;
}
}
return min;
}
private static int minInOrder(int[] array, int left, int right) {
// TODO Auto-generated method stub
int result = array[left];
for(int i=left+1;i<=right;i++) {
if(result > array[i]) {
result = array[i];
}
}
return result;
}
}