判断是否是2的幂
https://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/
https://blog.csdn.net/K346K346/article/details/53316953
Shift Right
int isPowerOfTwo (unsigned int x)
{
while (((x & 1) == 0) && x > 1) /* While x is even and > 1 */
x >>= 1;
return (x == 1);
}
Decrement and Compare
int isPowerOfTwo (unsigned int x)
{
return ((x != 0) && !(x & (x - 1)));
}
Complement and Compare
int isPowerOfTwo (unsigned int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
常用排序算法总结
排序算法大体可分为两种:
一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序,选择排序,插入排序,归并排序,堆排序,快速排序等。
另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序,基数排序,桶排序等。
排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。
算法图解
- 选择排序
- 递归
- 快速排序
- 散列表
- 广度优先搜索
- 狄克斯特拉算法
- 贪婪算法
- 动态规划
- K最近邻算法
常用算法的时间复杂度
二叉树遍历
前序遍历
利用了栈的先进后出的特性,首先遍历显示根节点,然后将右子树(注意是右子树不是左子树)压栈,最后将左子树压栈。由于最后时将左子树节点压栈,所以下一次首先出栈的应该是左子树的根节点,也就保证了先序遍历的规则。
中序遍历
首先将根节点所有的左子树节点压栈,然后一一出栈,每当出栈一个元素后,便将其右子树节点压栈。这样就可以实现首先出栈的永远是栈中的左子树节点,然后是根节点,最后时右子树节点,也就可以保证中序遍历的规则。
后序遍历
使用了两个栈来辅助,其中一个stackIn作为中间存储起到过渡作用,而另一个stackOut则作为最后的输出结果进行遍历显示。众所周知,栈的特性使LIFO(后进先出),那么stackIn在进行存储过渡时,先按照根节点->左孩子->右孩子的顺序依次压栈,那么其出栈顺序就是右孩子->左孩子->根节点。而每当循环一次就会从stackIn中出栈一个元素,并压入stackOut中,那么这时stackOut中的出栈顺序则变成了左孩子->右孩子->根节点的顺序,也就符合了后序遍历的规则。
层次遍历
使用了一个队列来辅助实现,队列是遵循FIFO(先进先出)的,与栈刚好相反,所以,我们这里只需要按照根节点->左孩子->右孩子的入队顺序依次入队,输出时就可以符合根节点->左孩子->右孩子的规则了。
图的遍历
广度与深度遍历
广度:队列
深度:栈
散列表
哈希(散列)技术既是一种存储方法,也是一种查找方法。
构造哈希函数的方法
构造哈希函数的目标在于使哈希地址尽可能均匀地分布在连续的内存单元地址上,以减少发生冲突的可能性,同时使计算尽可能简单以达到尽可能高的时间效率,这里主要看看两个构造哈希函数的方法。
(1)直接地址法
直接地址法取关键字的某个线性函数值为哈希地址,即h(key)=key 或 h(key)=a*key+b
其中,a、b均为常数,这样的散列函数优点就是简单、均匀,也不会产生冲突,但问题是这需要事先知道关键字的分布情况,适合查找表较小且连续的情况。由于这样的限制,在现实应用中,此方法虽然简单,但却并不常用。
(2)除留余数法
除留余数法采用取模运算(%)把关键字除以某个不大于哈希表表长的整数得到的余数作为哈希地址,它也是最常用的构造哈希函数的方法,其形式为:h(key)=key%p
解决哈希冲突的方法
(1)闭散列法
闭散列法时把所有的元素都存储在哈希表数组中,当发生冲突时,在冲突位置的附近寻找可存放记录的空单元。寻找“下一个”空位的过程则称为探测。
(2)开散列法
开散列法的常见形式是将所有关键字为同义词的记录存储在一个单链表中。我们称这种表为同义词子表,在散列表中只存储所有同义词子表的头指针。
伪随机数发生算法
Python 的伪随机数(pseudorandom number)生成器用的是梅森旋转(Mersenne
Twister)算法(https://en.wikipedia.org/wiki/Mersenne_Twister),它产生的随机数很难
预测且呈均匀分布
加密算法
对称加密
Blowfish
Blowfish能保证很好的加密速度,并且目前为止没有发现有效地破解方法。目前为止AES比Blowfish有更广的知名度。
AES
AES(Advanced Encryption Standard),又称Rijndael加密法
其他
scrypt
scrypt不仅计算所需时间长,而且占用的内存也多,使得并行计算多个摘要异常困难,因此利用rainbow table进行暴力攻击更加困难。
book
- 算法图解
- 编程之法:面试和算法心得