一些需要烂熟于心的代码

二叉树

非递归遍历

前序

/**
     * 先序非递归遍历
     * 访问一个节点时候,若该节点左右孩子节点都存在,按照右孩子左孩子顺序压栈,若只存在一个孩子节点,直接压栈该孩子节点
     */
    public void firstTravel(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        //压入根节点
        stack.push(root);
        //栈非空,弹栈遍历该节点,然后
        while (!stack.isEmpty()) {
            TreeNode node = stack.pop();
            System.out.print(node.val + " ");
            if (node.right != null)
                stack.push(node.right);
            if (node.left != null)
                stack.push(node.left);
        }
        System.out.println();
    }

中序

 /**
     * 中序非递归遍历
     * 思想:
     * 左-根-右:所以只要左孩子还有左子树就要先遍历左孩子的左子树
     * 1、从根节点开始将左孩子节点压栈,如果左孩子节点还有左子树继续将左孩子节点的左孩子节点压栈,一直这么持续操作,直到遇到null节点;
     * 2、此时栈顶节点就是该树(不特指整棵树)中序遍历第一个要访问的节点,弹出该节点;
     * 3、对该节点的右孩子节点重复1,2操作。
     */
    public void inTravel(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        while (node != null || !stack.isEmpty()) {
            //一直压入左孩子节点,直到压入null
            if (node != null) {
                stack.push(node);
                //左孩子节点可能为null
                node = node.left;
            }
            //栈顶元素为null就弹栈一次
            else {
                //此时栈顶元素就是以该栈顶元素作为根节点的树的第一个被访问节点
                node = stack.pop();
                System.out.print(node.val + " ");
                //右孩子节点可能为null
                node = node.right;
            }
        }
        System.out.println();
    }

后序

/**
     * 后续遍历非递归
     */
    public void lastTravel(TreeNode root) {
        Stack<TreeNode> stack = new Stack<>();
        TreeNode node = root;
        TreeNode pre = null;//记录上一次访问的节点
        while (!stack.isEmpty() || node != null) {
            //一直压入左孩子节点,直到压入null
            if (node != null) {
                stack.push(node);
                //左孩子节点可能为null,表示
                node = node.left;
            }
            //栈顶元素为null就弹栈一次
            else {
                //此时栈顶元素就是以该栈顶元素作为根节点的树的第一个被访问节点
                node = stack.pop();
                //栈顶节点存在右孩子,且右孩子节点就是上一次被访问的节点
                if (node.right == null || pre == node.right) {
                    System.out.print(node.val + " ");
                    pre = node;//更新状态
                    node = null;
                }
                //没有右孩子或者右孩子没有被访问
                else {
                    stack.push(node);
                    //右孩子节点可能为null
                    node = node.right;
                }
            }
        }
        System.out.println();
    }

层次

 public List<List<Integer>> levelOrder(TreeNode root) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        //we use LinkedList as a queue
        LinkedList<TreeNode> q = new LinkedList<TreeNode>();
        if(root == null) return res;
        TreeNode p = root;
        q.addLast(p);
        while(!q.isEmpty()){
            int tmpSize = q.size();
            List<Integer> tmpList = new ArrayList<Integer>();
            //Attention:i<tmpSize
            for(int i=0;i<tmpSize;i++){
                p = q.getFirst();
                q.poll();
                tmpList.add(p.val);
                if(p.left!=null)  q.addLast(p.left);
                if(p.right!=null) q.addLast(p.right);
            }
            res.add(tmpList);
        }
        return res;
    }

排序

快排

public static int partition(int[] numbers, int low,int high) {
        int temp = numbers[low]; //数组的第一个作为中轴
        while(low < high)  {     
            while(low < high && numbers[high] >= temp) high--;
            numbers[low] = numbers[high];//比中轴小的记录移到低端
            while(low < high && numbers[low] <= temp) low++;
            numbers[high] = numbers[low] ; //比中轴大的记录移到高端
        }
        numbers[low] = temp ; //中轴记录到尾
        return low ; // 返回中轴的位置
    }
public static void quickSort(int[] numbers,int low,int high) {
        if(low < high)   {
          int middle = partition(numbers,low,high); //将numbers数组进行一分为二
          quickSort(numbers, low, middle-1);   //对低字段表进行递归排序
          quickSort(numbers, middle+1, high); //对高字段表进行递归排序
        }    
    }

希尔

int[] arrary = {49, 38, 65, 97, 76, 13, 27, 49, 55, 04};
int[] dk = {5, 3, 1};

public void shellInsert(int[] array, int dk) {
        int temp = 0, j = 0;
        // 遍历所有分组:若元素之间的距离为dk,则为同一个分组
        for (int i = dk; i < array.length; i++) {
            // i,i-dk为同一个分组:对同一个分组的元素进行直接插入排序
            if (array[i] < array[i - dk]) {
                temp = array[i];
                for (j = i - dk; j >= 0 && temp < array[j]; j -= dk) {
                    // 后移dk
                    array[j + dk] = array[j];
                }
                // 定位
                array[j + dk] = temp;
            }
        }
    }

    public void shellSort(int[] array, int[] dk, int t) {
        // 依次按照分组间隔dk进行操作
        for (int i = 0; i < t; i++) {
            shellInsert(array, dk[i]);
        }
    }

归并

 public void mergeSort(int[] data) {
        if (data == null || data.length == 0)
            return;
        int len = data.length;
        // 只开辟一次辅助数组
        int[] temp = new int[len];
        mergeSortCore(data, 0, len - 1, temp);
    }
    // 将两个有序子数组合并[start-mid][mid+1,end],并将排序后数组写回原数组
    // temp:辅助数组
    public void merge(int[] data, int start, int mid, int end, int[] temp) {
        //前半段数组[start-mid];后半段数组[mid+1,end];一共为k个元素
        int i = start, j = mid + 1, k = 0;
        //子数组排序结果暂存于辅助数组中
        while (i <= mid && j <= end) {
            if (data[i] < data[j])
                temp[k++] = data[i++];
            else
                temp[k++] = data[j++];
        }
        //前半段数组有剩余
        while (i <= mid)
            temp[k++] = data[i++];
        //后半段数组有剩余
        while (j <= end)
            temp[k++] = data[j++];
        //将排序后的子数组写回原数组
        for (i = 0; i < k; i++)
            data[start + i] = temp[i];
    }
    public void mergeSortCore(int[] data, int start, int end, int[] temp) {
        //递归终止;当数组长度变为1是,停止拆分
        if (start == end)
            return;
        //拆分为左右两个子数组
        int mid = (start + end) / 2;
        mergeSortCore(data, start, mid, temp);//对左侧子数组递归排序;使得左侧子数组有序
        mergeSortCore(data, mid + 1, end, temp);//对右侧子数组递归排序;使得右侧子数组有序
        merge(data, start, mid, end, temp);//合并当前左右有序子数组
    }

括号匹配

// 碰到左括号压栈;碰到右括号不压栈,但是判断栈顶元素是否匹配
    public boolean matchJudge(String str) {
        HashMap<Character, Character> dict = new HashMap<>();
        dict.put('(', ')');
        dict.put('[', ']');
        dict.put('{', '}');
        Stack<Character> stack = new Stack();
        boolean res = false;
        int len = str.length();
        //逐个字符
        char ch = '\0';
        char p = '\0';
        for (int i = 0; i < len; i++) {
            ch = str.charAt(i);
            // 左括号,压栈
            if (dict.containsKey(ch))
                stack.push(ch);
                // 右括号
            else if (dict.containsValue(ch)) {
                // 栈顶元素与右括号匹配
                if (!stack.isEmpty() && dict.get(stack.peek()) == ch)
                    stack.pop();
                    // 不匹配
                else return false;

            }
        }
        return stack.isEmpty() ? true : false;
    }

    //测试数据
    public String getMatchData(int index) {
        String str = "";
        String str1 = "{[(1+2)/(3+4)]-[[(1+2)/(3+4)]]}";
        String str2 = "{[()]}";
        String str3 = "{[]]}";
        String str4 = "[()(]";
        String str5 = "([)]";
        String str6 = "({}[]]])";
        String str7 = "[()](((";
        switch (index) {
            case 1: { str = str1; break; }
            case 2: { str = str2; break; }
            case 3: { str = str3; break; }
            case 4: { str = str4; break; }
            case 5: { str = str5; break; }
            case 6: { str = str6; break; }
            case 7: { str = str7; break; }
        }
        return str;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值