入门算法(面试经典问题)
1.快速排序(快排) 时间复杂度O(nlogn) 最坏时间复杂度O(n^2)
基本思想:
选择一个基准数作为参照物,由2边向中进行检索,先从右边检索比基准数小的,再从左边检索比基准数大的,然后交换2个元素,再进行检索!
package quicksortdemo;
public class Demo1QuickSort {
public static void main(String[] args) {
int[] array = new int[]{3,4,1,6,2};
forEach("未排好的:", array);
quickSort(array,0,array.length-1);
forEach("排好序的:", array);
}
/**
* @param arr 数组
* @param left 左边索引位置
* @param right 右边索引位置
*/
private static void quickSort(int[] arr, int left, int right) {
// 左边索引不能大于右边索引 否则直接return
if (left > right) {
return;
}
// 定义基准数 最左边下标的位置
int basic = arr[left];
// 定义指针指向最左边的数
int i = left;
//定义指针指向最右边的数
int j = right;
// 当i和j 不相遇的时候进行检索
while (i != j) {
//先由j从右往左检索比基准数小的,检索到了就停下
// 就是说 如果当前索引位置的元素值比基准数大或者等于 就继续检索
while (arr[j] >= basic && i < j) {
j--;
}
//i从左往右检索
while (arr[i] <= basic && i < j) {
i++;
}
// 然后i再从左往右检索比基准数大的 进行交换位置
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 如果跳出while 循环代表他们指针相遇 此时将 指针指向的元素赋值给基准数 再将基准数的元素赋值给
// 指针指向的元素
arr[left] = arr[i];
arr[i] = basic;
// 递归调用
quickSort(arr,left,i-1);
quickSort(arr,i+1,right);
}
private static void forEach(String start , int[] arr){
StringBuilder builder = new StringBuilder();
for(int i = 0 ;i<arr.length;i++){
builder.append(arr[i]+"\t");
}
System.out.println(start + " " + builder.toString());
}
}
2.冒泡排序法 时间复杂度O(n^2)
基本思想:
相邻的2个元素进行比较,小的往前大的往后,第一轮比较得出一个最小的,共比较数组的length-1轮
package quicksortdemo;
public class Demo2Sort {
public static void main(String[] args) {
int[] array = new int[]{4,5,3,1,2,};
sort(array);
forEach("排好序的:", array);
}
/**
* 比较的是4轮 每轮选出一个大的数字排到前面
* @param arr
*/
private static void sort(int[] arr){
// 轮
for(int i =1;i<arr.length;i++){
for(int j = 0;j< arr.length-i;j++){
// 如果前面的数字比后面的数字大 那么交换位置
if(arr[j] > arr[j+1]){
int temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
}
private static void forEach(String start , int[] arr){
StringBuilder builder = new StringBuilder();
for(int i = 0 ;i<arr.length;i++){
builder.append(arr[i]+"\t");
}
System.out.println(start + " " + builder.toString());
}
}
3.选择排序 时间复杂度O(n^2) 排序快于 冒泡排序
基本思想:
第一个元素和其他元素进行比较,小的排到前面,依次进行比较
package quicksortdemo;
public class Demo3Sort {
public static void main(String[] args) {
int[] array = new int[]{1,3,2,6,4};
sort(array);
forEach("排好序的:",array);
}
// 选择排序
private static void sort(int[] arr){
// 拿第一个元素和后面的元素进行比较 大的往前 降序排列
for (int i = 0; i < arr.length-1; i++) {
for(int j = i ; j<arr.length ; j++){
if(arr[i]>arr[j]){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
private static void forEach(String start , int[] arr){
StringBuilder builder = new StringBuilder();
for(int i = 0 ;i<arr.length;i++){
builder.append(arr[i]+"\t");
}
System.out.println(start + " " + builder.toString());
}
}
4.归并排序 时间复杂度O(nlogn) 最坏时间复杂度 O(nlogn) 分而治之 核心递归加merage 合并
5.二分查找法
核心思想:
二分查找对半分,递归查找。
package quicksortdemo;
/**
* 二分查找对半分
*/
public class Demo4{
public static void main(String[] args) {
// 二分查找法必须是已经排好序的
int[] array = new int[]{1,2,3,5,6};
System.out.println(search(array,6,0,array.length-1));
}
/**
*
* @param arr 数组
* @param n 找哪个元素
* @param left 起始下标
* @param right 结束下标
*/
public static int search(int[] arr,int n , int left,int right){
if(left>right){
return -1;
}
int middle = (left+right)/2;
int value = arr[middle];
//如果值大于要找的数字
if(value>n){
// 去左边数组找
return search(arr,n,left,middle-1);
}else if(value < n ){
// 小于的话去右边数组找
return search(arr,n,middle+1,right);
}else {
// 刚好的时候是直接输出下标位置
return middle ;
}
}
}