数据结构和算法自我学习[第一天0409]

311 阅读4分钟

写作原因

为了更好的掌握数据结构和算法!

声明: 记录的是自己的总结,一部分抄写了网络的文章,记得文章来源必定会声明转载,若没写,侵权了请联系。 参考网址:

算法题目

题目:排序算法

  • 冒泡排序
  • 插入排序
  • 快速排序

题目:数组相关

  • 找出数组中某个数字出现的次数超过数组长度的一半
  • 调整数组顺序使奇数位于偶数前面

具体代码实现

冒泡排序

    /**
     * 注意点:是两个相邻元素进行比较,用两次循环。
     * 冒泡排序:一次比较两个相邻元素,把最大值往后排,多次进行即可排好。
     *
     * @param list
     * @return
     */
    public static List bubbling(List<Integer> list) {
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.size() - i - 1; j++) {
                if (list.get(j) > list.get(j + 1)) {
                    int temp = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, temp);
                }
            }
        }
        return list;
    }
   

插入排序

    /**
     * 插入排序
     * 思路注意点:
     * p代表当前的值位,n代表要插入的值,判断-若p代表的值大于n,则把p代表的值往后放,p本身倒退,-若大于了,即直接放p+1的位置。
     * 代码实现注意点:
     * - 每次的插入值要提取出来
     * - 注意判断p要在前,不然会出现越界
     *
     * @param list
     * @return
     */
    public static List insert(List<Integer> list) {
        for (int i = 0; i < list.size() - 1; i++) {
            int p = i;
            int n = list.get(i + 1);
            while (p >= 0 && list.get(p) > n) {
                list.set(p + 1, list.get(p));
                p--;
            }
            list.set(p + 1, n);
        }
        return list;
    }

快速排序

        /**
         * 一次循环:从后往前比较,用基准值和最后一个值比较,如果比基准值小或等于的交换位置,如果没有继续比较下一个,
         * 直到找到第一个比基准值小的值才交换。找到这个值之后,又从前往后开始比较,如果有比基准值大的,交换位置,
         * 如果没有继续比较下一个,直到找到第一个比基准值大或等于的值才交换。
         * 结束条件:前往后的索引>从后往前的索引,结束第一次循环,此时,对于基准值来说,左右两边就是有序的了。
         * 此时就需要从索引两边进行递归回调即可。
         * 思路来源网络
         * 
         * @param list
         * @param low
         * @param height
         * @return
         */
    public static List quickSort(List<Integer> list, int low, int height) {
        int start = low;
        int end = height;
        int base = list.get(start);
        while (end > start) {
            //找到小于等于基准的值
            while (end > start && list.get(end) >= base) {
                end--;
            }
            //找到了就把p代表的值放q中,q代表的值放p中
            int temp = list.get(end);
            list.set(end, list.get(start));
            list.set(start, temp);
            //找到大于等于基准的值
            while (end > start && list.get(start) <= base) {
                start++;
            }
            //找到了就把p代表的值放q中,q代表的值放p中
            int temp1 = list.get(end);
            list.set(end, list.get(start));
            list.set(start, temp1);
        }
        //进行递归操作
        if (start > low) {
            quickSort(list, low, start - 1);
        }
        if (end < height) {
            quickSort(list, end + 1, height);
        }
        return list;
    }

找出数组中某个数字出现的次数超过数组长度的一半

    /**
     * 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.
     * 注意点:
     *      if (int len = array.length <= 1) 这种写法不可以
     * @param array
     * @return
     */
    public static int moreThanHalfNumSolution(int[] array) {
        //两种思路:先排好序,那么中间一个数就可能是出现最多情况
        //采用第二:阵地法,相同+1,不同-1,若为0就换人

        int len = array.length;
        if (len <= 1) {
            if (len == 1) {
                return array[0];
            }
            return 0;
        }

        //首先得有个计数当前士兵,和遇到的敌人
        int count = 1;
        int person = array[0];

        for (int i = 1; i < len; i++) {
            //对第一个和第二个进行判断
            if (person != array[i]) {
                //不等说明两个都杀
                count--;
                //判断一下是否有为0了
                if (count == 0 && i < len - 1) {
                    person = array[i + 1];
                    count = 1;
                }
            } else {
                //等于的话就进行+1
                count++;
            }

        }
        //得到当前候选人,但要确认
        //计算半长
        count = 0;
        int halfLength = len >> 1;
        for (int i = 0; i < array.length; i++) {
            //得到候选人出现的次数
            if (array[i] == person) {
                count++;
            }
        }
        //进行比较
        if (count > halfLength) {
            return person;
        } else {
            return 0;
        }
    }

调整数组顺序使奇数位于偶数前面

    /**
     * 题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,
     * 所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
     * 方法:使用了空间换时间,是稳定的算法
     * 注意点:if((array[i] & 1) == 1) 需要用到括号
     * @param array
     */
    public static void reOrderArray(int [] array) {
        //防止空
        if(array == null){
            return;
        }
        //创建一个新数组
        int arrayLen = array.length;
        int[] newArray = new int[arrayLen];
        int count = 0;

        //先求出原数组有多少个奇数,为了把得到的偶数可以有位置放
        for(int i=0; i<arrayLen; i++){
            if((array[i] & 1) == 1){
                //说明是奇数
                count++;
            }
        }
        //进行遍历每个值
        int left = 0;
        int right = count;
        for(int j=0; j<arrayLen; j++){
            if((array[j] & 1) == 1){
                newArray[left] = array[j];
                left++;
            } else {
                newArray[right] = array[j];
                right++;
            }
        }
        for(int k=0; k<arrayLen; k++){
            array[k] = newArray[k];
        }
    }