Skip to content

Junjie1212/algorithm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

1.STL:

(1).vector
(2).set
(3).queue
(4).stack
(5).string

2.库:

(1).#include<stdio.h>
    scanf()
    printf()
    getchar()
    putchar()
    gets()
    puts()
    sscanf()
    sprintf()

(2)#include<stdlib.h>

(3)#include<time.h>

(4)#include<math.h>
    fabs()
    sqrt()
    pow()
    floor()
    ceil()
    round()

(5)#include<algorithm>
    max()、min()、abs()
    swap()
    reverse()
    next_permutation()
    fill()
    sort()
    lower_bound(),upper_bound()

3.位运算

(1) 与 &
    或 |
    反 ~
    异或 ^
(2) 左移<<
    右移>>
(3) 原码
    反码
    补码
(4)位运算判断奇偶数
(5)判断二进制位是1还是0
(6)异或法交换两个整形变量的值
(7)不用判断语句,求整数的绝对值

(8)例题:如何找数组中唯一成对的那个数
(9)例题:找出落单的那个数
(11)例题:二进制中1的个数
(12)例题:是不是2的整数次方
(13)例题:将整数的奇偶位互换

4.递归

关键就是找到如何将大问题分解为小问题的规律,并且基于此写出递推公式,然后再推敲终止条件,如求n的阶乘
(1)找重复-->找子问题 4321
(2)找变化-->找重复中的变化量作为参数 n变化
(3)找边界-->找参数变化趋势设计出口  n=1截止

5.树

alt text

1.树的概念
    (1)节点的度:一个节点含有的子树的个数称为该节点的度;如上图:A的度为6
    (2)叶节点或终端节点:度为0的节点称为叶节点;如上图:B、C、H、I...等节点为叶节点
    (3)非终端节点或分支节点:度不为0的节点;如上图:D、E、F、G...等节点为分支节点
    (4)双亲节点或父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;如上图:A是B的父节点
    (5)孩子节点或子节点:一个节点含有的子树的根节点称为该节点的子节点;如上图:B是A的孩子节点
    (6)兄弟节点:具有相同父节点的节点互称为兄弟节点;如上图:B、C是兄弟节点
    (7)树的度:一棵树中,最大的节点的度称为树的度;如上图:树的度为6
    (8)节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推;
    (9)树的高度或深度:树中节点的最大层次;如上图:树的高度为4
    (10)节点的祖先:从根到该节点所经分支上的所有节点;如上图:A是所有节点的祖先
    (11)子孙:以某节点为根的子树中任一节点都称为该节点的子孙。如上图:所有节点都是A的子孙
    (12)森林:由m(m>0)棵互不相交的多颗树的集合称为森林;(数据结构中的学习并查集本质就是一个森林)

2.树的表示:
    (1)双亲表示法
    (2)孩子表示法
    (3)孩子兄弟表示法
3.二叉树
    (1)存储结构
    (2)满二叉树,完全二叉树,二叉搜索数
    (3)性质
       性质一:若规定根节点的层数为1,则一棵非空二叉树的第 i 层上最多有 2 ^ (i - 1) 个节点(满二叉树)
       性质二:若规定根节点的层数为1,则深度为 h 的二叉树的最大节点数是2 ^ h - 1(满二叉树)
       性质三:对任何一棵二叉树,如果度为0的叶节点个数是X0,度为2的节点个数是X2,则 X0 =  X2 + 1;
       性质四:若规定根节点的层数是1,具有 n 个节点的满二叉树的深度为 h = log ( n + 1) 

    (4)二叉树遍历
        前序(先根)遍历:根节点、左子树、右子树 (递归,非递归)
        中序(中根)遍历:左子树、根节点、右子树
        后序(后根)遍历:左子树、右子树、根节点
        层序遍历:BFS

6.分治

alt text

(1)分解成子问题->递归处理子问题->合并子题
(2)如归并排序(手写一下)
(3)列题:计算pow(x, n)

7.二分查找

(1)查找一次砍掉一半,前提是有序
(2) left=0,right=size-1
    while(left<=right>)
    mid=left+(left-right)>>1 
    if()left++     if()right--

8.DFS

(1)一条路走到底,不撞南墙不回头,遇到南墙再转退一步
(2)递归思想,本质是栈,非递归也能实现
(3)应用场景:二叉树搜索,图搜索
(4)123全排列
    //从for i=1开始  ->表示进入下一个dfs
    1—>2->3 输出123  (a[1]=1) step=3
    1->2 3的状态恢复0 step=2
    1    3的状态恢复0 2的状态恢复0 step也恢复到1
    最开始的i++ i=2
    a[step] = i 所以a[1]=2
(5)基本模板
   void dfs(int step){
    判断边界
    尝试每一种可能 for(i=1;i<=n;i++){
        继续下一步 dfs(step+1)
        }
    返回

9.模拟

(1)日期模拟
   20130101
   20130105
   差值5

   不妨假设第一个日期早于第二个日期(否则进行交换)。
   这种求日期之间相差天数的题目有一个很直接的思路,即令日期不断加一天,直到第一个日期等于第二个日期为止,即可统计出答案。
   具体处理时,如果当加上一天之后天数d 等于当前月份m 所拥有的的天数加1,那么就令月份m 加1、同时置天数d 为1号(即把日期变为下个月的1号);
   如果此时月份m 变成了13,那么就令年份y 加1、同时置月份m 为1月(即把日期变成下一年的1月)

(2)进制转换
对于一个P进制的数,如果要转换成Q进制,需要分为两步:
    1.将P进制数x 转换为十进制数y
        对一个十进制数 a = d1d2...dn,它可以写成这个形式:
        a = d1 * 10^(n-1) + d2 * 10^(n-2) + ... + dn * 10^0
        同样的,如果P进制数x 为a1a2...an,用下面这种方法即可转换为十进制数 y:
        y = a1 * P^(n-1) + a2 * P^(n-2) + ... an * P^0

    2.将十进制数y 转换为Q进制数z
        采用“除基取余法”。所谓“基”,是指将要转换成的进制Q,因此除基取余法的意思就是每次将待转换数除以Q,然后将得到的余数作为低位存储,
        而商则继续除以Q并进行上面的操作,最后当商为0时,将所有位从高到低输出就可以得到z 。 
(3)字符串
   1.isalpha()
   2.isalnum()
   3.islower()
   4.isupper()
   5.char c = toupper(a)
   6.char c = tolower(a)
   7.strlwr() 
   8.strupr()
   9.isdigit()
   10.to_string()

(4)等等

10.双指针

(1)普通的指针:多是两个指针往同一个方向移动
(2)对撞的指针(多用于有序的情况):两个指针面对面移动(比如一头一尾往中间移动)
(3)快慢的指针:慢指针+快指针

(4)例题 有序两数相加
(5)例题 反转字符串
(6)例题 救生艇

11.DFS

alt text (1)是从根节点开始,沿着树的宽度遍历树的节点 (2)遍历到一个结点时,如果这个结点有左(右)孩子结点,依次将它们加入队列

12.动态规划

(1)把原问题分解为相对简单的子问题,求解复杂问题的方法(特殊的分治)
(2)适用 重叠子问题和最优子结构性质的问题
(3)一旦一个子问题求解得到结果,以后的计算过程就不会修改它,具有天然剪枝功能,从而减少计算量
(4)两种解决问题的方式 自顶向下记忆化搜索,自底向上递推

顾名思义,记忆化搜索肯定也就和“搜索”脱不了关系, 前面讲解的递归、DFS和BFS想必大家都已经掌握的差不多了,它们有个最大的弊病就是:低效!原因在于没有很好地处理重叠子问题。那么对于记忆化搜索呢,它虽然采用搜索的形式,但是它还有动态规划里面递推的思想,巧就巧在它将这两种方法很好的综合在了一起,简单又实用。
记忆化搜索,也叫记忆化递归,其实就是拆分子问题的时候,发现有很多重复子问题,然后再求解它们以后记录下来。以后再遇到要求解同样规模的子问题的时候,直接读取答案。


递推是把问题划分为若干个步骤,每个步骤之间,或者是这个步骤与之前的几个步骤之间有一定的数量关系,可以用前几项的值表示出这一项的值,这样就可以把一个复杂的问题变成很多小的问题。
递推算法注意的是设置什么样的递推状态,因为一个好的递推状态可以让问题很简单。最难的是想出递推公式,一般递推公式是从后面向前想,倒推回去。

Releases

No releases published

Languages