二分查找
二分查找算法也称为折半搜索、二分搜索
在有序数组中查找某指定元素的搜索算法。企业面试常见考试的类型。
* 有序:二分查找法只适用于有序的数组,对于无序的数组如果想要使用二分查找法查找某数据,必须先对目标数组进行排序。
- 原理:二分查找法,即对一个有序的数组每次取数组中间下标的数据与目标key值进行比较,快速缩小查找范围。
/**
* 6,8,10,12,14,16,18,20--midVal = 12 > key
* 6,8,10 --midVal = 8 < key
* 10 --midVal = 10 ==key 查找成功
*/
public class Test01_BinarySearch {
public static void main(String[] args) {
int[] a = {6,8,10,12,14,16,18,20};// 测试数组
int key = 10;// 目标key值
int index = binarySearch(a,key);// 使用我们写的二分查找法进行查找
System.out.println("binarySearch:"+key+" index:"+index);
int arrays = Arrays.binarySearch(a, key);// 调用Java官方提供的二分查找法查找数据
System.out.println("Arrays:"+key+" index:"+arrays);
}
private static int binarySearch(int[] a, int key) {
int low = 0;// 记录最小下标
int high = a.length-1;// 记录最大下标
while(low <= high){// 当low > high时说明数组中没有查找的key值
int mid = (low+high) >>> 1;// 计算中间下标
int midVal = a[mid];// 取得中间下标对应的值
if(midVal > key){// 将中间值与目标key值进行比较
high = mid-1;// 查找范围减半
}else if(midVal < key){
low = mid+1;
}else{
return mid;
}
}
return -1;// 查找数据不存在
}
}
排序
排序是计算机程序设计中的一种重要操作,是指将一个任意的序列,排列成一个关键字有序的序列。
选择排序
- 原理:每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。
public class Test02_SelectSort {
public static void main(String[] args) {
int[] a = new int[10];
Random random = new Random();
for(int i=0;i<a.length;i++){
a[i] = random.nextInt(100);
}// 利用随机数产生一个随机数组
System.out.println(Arrays.toString(a));
selectSort(a);// 排序
System.out.println(Arrays.toString(a));
}
// 选择排序,降序
static void selectSort(int[] a){
for(int i=0;i<a.length;i++){// 外层循环每一趟完成一个位置上数据的排序
// 内层循环将该位置上的元素与其他所有元素进行比较,确定该位置上的元素,如第一次找到最大值放在第一个
for(int j=i+1;j<a.length;j++){
if(a[j]>a[i]){// 如果有元素大于该位置上的元素,就交换两个元素
int t = a[i];
a[i] = a[j];
a[j] = t;
}
}
}
}
}
冒泡排序
- 原理:依次比较相邻的两个数,将小数放在前面,大数放在后面。升序
public class Test03_BubbleSort {
public static void main(String[] args) {
int[] a = new int[10];
Random random = new Random();
for(int i=0;i<a.length;i++){
a[i] = random.nextInt(101);
}
System.out.println(Arrays.toString(a));
bubbleSort(a);
System.out.println(Arrays.toString(a));
}
// 冒泡排序
static void bubbleSort(int[] a){
for(int i=1;i<a.length;i++){
for(int j=0;j<a.length-i;j++){// 内层循环循环一次选出一个最大的数放在数组最后
if(a[j] > a[j+1]){
int t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
}
}
插入排序
- 原理:将数据插入到已经排好序的有序数据中,得到一个新的、个数加一的有序数据。
public class Test04_InsertSort {
public static void main(String[] args) {
int[] a = new int[10];
Random random = new Random();
for (int i = 0; i < a.length; i++) {
a[i] = random.nextInt(101);
}
System.out.println(Arrays.toString(a));
insertSort(a);
System.out.println(Arrays.toString(a));
}
static void insertSort(int[] a) {
for (int i = 1; i < a.length; i++) {
int k = a[i];
int j;
for (j = i - 1; j >= 0 && k > a[j]; j--) {
a[j + 1] = a[j];
}
a[j + 1] = k;
}
}
}
快速排序
快速排序的过程是首先选择一个基准,如下标为0的数值。先从后往前找一个比基准大的数,然后将此数值与基准交换,再从前往后找一个比基准小的数值,然后在将此小数值与基准交换。如此反复…
- 原理:快速排序使用分治法来设计算法:取一个基准元素,拆分之后基准元素左边的都比基准元素大,右边的元素都比基准元素小,然后分别对两个子数组排序。降序
public class Test05_QuickSort {
public static void main(String[] args) {
int[] a = new int[10];
Random random = new Random();
for(int i=0;i<a.length;i++){
a[i] = random.nextInt(100);
}
System.out.println(Arrays.toString(a));
quickSort(a,0,a.length-1);
System.out.println(Arrays.toString(a));
}
private static void quickSort(int[] a, int low, int high) {
if(low>=high){// 递归的中止条件
return;
}
int l = low;
int h = high;
boolean isRight = false;
while(l < h){
if(a[l] < a[h]){
int t = a[l];
a[l] = a[h];
a[h] = t;
isRight = !isRight;
}
if(isRight){
l++;
}else{
h--;
}
}
quickSort(a,low,l-1);// 对子数组进行排序
quickSort(a,l+1,high);
}
}