数据结构和算法

        数据结构和算法是计算机发展中纯编程模块重要的总结成果,常见算法和数据结构针对现有的计算机架构、常用业务场景、常见需求进行设计与归纳得出,单纯学习算法的过程比较困难,学习过程也较费劲,需要极大的意志力和兴趣支持。

个人和这块知识的过往

        CS专业出身,大概本科三年级学习该内容,虽然也有实践,敲过各类算法,数据结构,却只是停留在大概印象层面。

        校招找工作阶段,好好“刷了一波题”,经过自发努力,当时也多少可以AC部分题目。

        终于,工作一段时间,不得不反思,总结了,痛定思痛,写吧。

        数据结构暂不涉及,多撸题,慢慢就差不多了,本文以算法为主,本文不配图,如有需要自行搜索,有图可以帮助加速理解。

1. 排序算法

        以快速排序为例——JDK中的容器在sort时使用该算法,以堆排序为例——曾经面试被问过,没意识到还有这。

1.1快速排序(升序)

a.在区间start,end内,以第一个数为基准值;

b.从末尾往前找小于基准值的数,放置在基准值位置;

c.从第一个数开始找大于于基准值的数,找到则放置在上一个被移动的位置上;

d.循环bc,直到start==end,得到基准值位置pos;

分别对start,pos-1 区间 和 pos+1,end区间递归处理

1.2堆排序:

  • 根节点是最值
  • R[i].lchild = R[2 * i + 1]
  • R[i].rchild = R[2 * i + 2]
  • R[i].parent = R[(i - 1) / 2]
  • 堆的存储可以使用线性表
  • 满二叉树
  • 入堆加末尾,出堆将末尾补根

1.2.1构造堆(小顶堆为例):

在线性表上,从第二个节点开始到最后一个节点,各节点和父节点比较,不满足条件则和父节点交换,直到满足堆的条件(到达根节点,或小于父节点,对于新加的节点,只有满足小于父节点,则满足堆的条件)。

public static void heap(int[] data, int n) {
    for (int i = 1; i < n; i++) {
        int t = i;
        while (t != 0 && data[parent(t)] >= data[t]) {
            swap(data, t, parent(t));
            t = parent(t);
        }
    }
}
private static int parent(int t) {
    return (t - 1) / 2;
}

1.2.1出堆

在堆里面,出堆指的是根节点元素出堆,元素出堆,不满足堆条件,将最后一个元素补至根节点,调整堆:即将根元素下沉至合适位置,使得二叉树满足堆条件。

下沉过程:和子节点比较,同较小的节点交互位置,直到小于所有节点。

public static int pollMin(int[] data) {
    int ret = data[0];
    data[0] = data[data.length - 1];
    siftDown(data, data.length - 1);
    return ret;
}
private static void siftDown(int[] data, int n) {
    int i = 0;
    while (true) {
        if (i >= n - 1) break;
        // find max in i, i.lchild, rchild
        int l = 2 * i + 1;
        int r = 2 * i + 2;
        int min = i;
        if (l <= n - 1 && data[l] < data[i]) min = l;
        if (r <= n - 1 && data[r] < data[min]) min = r;
        // 当前节点已经最小则调整结束
        if (min == i) break;
        swap(data, i, min);
        i = min;
    }
}

1.2.3入堆

加在末尾,并上浮,直到根或满足堆条件。

public static void addMin(int[] data, int x) {
    data[data.length - 1] = x;
    int i = data.length - 1;
    while (parent(i) >= 0 && data[i] < data[parent(i)]) {
        swap(data, i, parent(i));
        i = parent(i);
    }
}

1.2.4堆排序

根节点出堆后,将当前末尾元素补至根,下沉根节点,调整堆。

public static void addMin(int[] data, int x) {
    data[data.length - 1] = x;
    int i = data.length - 1;
    while (parent(i) >= 0 && data[i] < data[parent(i)]) {
        swap(data, i, parent(i));
        i = parent(i);
    }
}

1.3二叉查找树

递归判断是否满足条件,左边严格小于根,右边严格大于根。

对于根节点,如果为空,则满足条件,否则需要满足左右子树为二叉排序树,同时值的大小满足排序条件。

boolean isBinarySortedTree(Node root, long min, long max){
    if (root == null) return true;
    return isBinarySortedTree(root.left, Long.MIN_VALUE, root.val) && 
           isBinarySortedTree(root.right, root.val, Long.MAX_VALUE) && 
           root.val > min &&
           root.val < max;
}

————————分割线,未来继续————————

2.图

图使用二维矩阵、或者邻接表表示,行标代表节点,存储各节点的出度。

3.回溯法

n皇后

子集

去重子集

4.动态规划

最长回文子序列

最大正方形

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackie_05

oo

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值