常见的算法

1. 说明

这里的算法主要是自己这段时间为了面试复习而记录的,只符合自己的阅读习惯,且只是用代码实现了一下,并没有详细的原理介绍。

2. 常见的算法

面试时要会写如下五种常见的算法
2.1 冒泡排序
①、比较相邻的元素。如果第一个比第二个大,就交换他们两个。
②、对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数(也就是第一波冒泡完成)。
③、针对所有的元素重复以上的步骤,除了最后一个。
④、持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
时间复杂度为O(n^2)

2.2 快速排序(冒泡改进版)
①、先通过第一趟排序,将数组原地划分为两部分,其中一部分的所有数据都小于另一部分的所有数据。原数组被划分为2份
②、通过递归的处理, 再对原数组分割的两部分分别划分为两部分,同样是使其中一部分的所有数据都小于另一部分的所有数据。 这个时候原数组被划分为了4份
③、就1,2被划分后的最小单元子数组来看,它们仍然是无序的,但是它们所组成的原数组却逐渐向有序的方向前进。
④、这样不断划分到最后,数组就被划分为多个由一个元素或多个相同元素组成的单元,这样数组就有序了。
时间复杂度O(nlogn)

2.3 选择排序
①、从待排序序列中,找到关键字最小的元素
②、如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换
③、从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束
时间复杂度为O(n^2)

2.4 直接插入排序
直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止
时间复杂度为O(n^2)

2.5 希尔排序(直接插入排序改进版)
是直接插入排序的改进,希尔排序通过加大插入排序中元素的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项能够大跨度的移动。当这些数据项排过一趟序后,希尔排序算法减小数据项的间隔再进行排序,依次进行下去,最后间隔为1时,就是我们上面说的简单的直接插入排序。
时间复杂度为O(n^(1.3—2))

3. 代码实现

/**
 * 1.冒泡排序  对比的次数是N-1次,两两比较,将最大的是挪到最后    经过N次排序,最后的N个数是有序的
 * 要点:1.标识符,如果第一次没有变化,则是有序的   2.排序的次数length-1    3.第i次比较的范围 0到length-i(i从1开始)
 *
 * @param array 待排序的数组
 * @return 排好序的数组
 */
public int[] bubbleSort(int[] array) {
    for (int i = 1; i < array.length; i++) {
        for (int j = 0; j < array.length - i; j++) {
            if (array[j] > array[j + 1]) {
                int temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
        System.out.println("冒泡第" + i + "次排序的结果为");
        display(array);
    }
    return array;
}


/**
 * 2.选择排序   需要N-1轮比较   每一次都是讲最小的数选择出来,插入到当前需要排序的位置
 * 要点:1.比较的轮数  len -1 2.每一轮待插入元素的位置  3.比较,如果该位置不是最小的数值,将最小的数和待排序的数对调
 *
 * @param array 待排序的数组
 * @return 已经排好序的数组
 */
public int[] choiceSort(int[] array) {
    for (int i = 0; i < array.length - 1; i++) {
        int min = i;
        for (int j = i + 1; j < array.length; j++) {
            if (array[j] < array[min]) {
                min = j;
            }
            if (i != min) {
                int temp = array[i];
                array[i] = array[min];
                array[min] = temp;
            }
        }
        System.out.println("选择第" + i + "次排序的结果为");
        display(array);
    }
    return array;
}


/**
 * 3.直接插入排序
 * 要点:首先要选择好待排序的那个数,在while循环中参与比较的数是temp,待比较的数
 *
 * @param array 倒排序的数组
 * @return 排好序的数组
 */
public int[] straightInsert(int[] array) {
    for (int i = 0; i < array.length - 1; i++) {
        int j = i + 1;
        int temp = array[j];
        while (j > 0 && temp < array[j - 1]) {
            array[j] = array[j - 1];
            j--;
        }
        array[j] = temp;
        System.out.println("直接插入第" + i + "次排序的结果为");
        display(array);
    }
    return array;
}

/**
 * 4.快速排序-冒泡排序的改进版,原理是选择一个基准位,每一次元数组分成两部分,一部分比基准数大,另一部分比基准数小
 * 注意:这个是简单版的快速排序,直接选择第一个数为基准数
 * 以下例子利用了分治算法的快速排序,选择一个目标数字,将待排序的数组分成两个,
 * 一部分都比这个数字大,一部分都比这个数字小
 * <p>
 * <p>
 * 减少冒泡排序过程中比较的次数
 */
public void quickSort(int[] arr, int low, int high) {
    int i, j, base, temp;
    if (low > high) {
        return;
    }
    i = low;
    j = high;
    //base是基准位,选择第一个数字为基准位
    base = arr[low];
    while (i < j) {
        //先看右边,依次往左递减
        while (base <= arr[j] && i < j) {
            j--;
        }
        //再看左边,依次往右递增
        while (base >= arr[i] && i < j) {
            i++;
        }
        //如果条件满足则交换
        if (i < j) {
            temp = arr[j];
            arr[j] = arr[i];
            arr[i] = temp;
        }
    }
    //最后将基准与i和j相等位置的数字调换,因为在上述交换的过程中,base上的数据肯定是不变的,也就是arr[low]不变
    arr[low] = arr[i];
    arr[i] = base;
    //递归调用左半边
    quickSort(arr, low, j - 1);
    //递归调用右半边,因为数字J在的位置已经是有序的,所以不再参与排序
    quickSort(arr, j + 1, high);

}


/**
 * 2h的shell排序,是直接插入排序的改进,希尔排序通过加大插入排序中元素的间隔,并在这些有间隔的元素中进行插入排序,从而使数据项能够大跨度的移动。
 *
 * @param array
 */
public void shellSortFor2h(int[] array) {
    int step;
    int len = array.length;
    for (step = len / 2; step > 0; step /= 2) {
        for (int i = step; i < len; i++) {
            int j = i;
            int temp = array[j];
            if (array[j] < array[j - step]) {
                while (j - step >= 0 && temp < array[j - step]) {
                    array[j] = array[j - step];
                    j -= step;
                }
                array[j] = temp;
            }
        }
    }
}


//遍历显示数组
public static void display(int[] array) {
    for (int i = 0; i < array.length; i++) {
        System.out.print(array[i] + " ");
    }
    System.out.println();
}

public static void main(String[] args) {
    AlgorithmInteview algorithmInteview = new AlgorithmInteview();
    int[] array = {9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 0};
    //未排序数组顺序为
    System.out.println("未排序数组顺序为:");
    display(array);
    System.out.println("-----------------------");
    algorithmInteview.straightInsert(array);
    System.out.println("-----------------------");
    System.out.println("经过排序后的数组顺序为:");
    display(array);
}
posted @ 2020-11-27 18:12  CherrieLin  阅读(103)  评论(0编辑  收藏  举报