树
1.二分查找树,检索任意数据的比较次数不会多于树的高度,搜索效率为O(log n)。
2.平衡二叉树,一棵树的左右两个子树的高度差的绝对值不会超过1。
3.满二叉树,每一层上的所有结点都有两个子结点。在满二叉树中,每一层上的结点数都达到最大值,即在满二叉树的第k层上有2k-1个结点,且深度为m的满二叉树有2m-1个结点;完全二叉树:一颗二叉树最多只有最下面的两层节点度数可以小于2,并且最下面一层的节点都集中在该层最左边的连续位置上。满二叉树肯定是完全二叉树,完全二叉树不一定是满二叉树。
4.二叉树的遍历
前序遍历:根节点->左子树->右子树
中序遍历:左子树->根节点->右子树
后序遍历:左子树->右子树->根节点
二叉树定义如下:
class TreeNode{
public:
TreeNode *left;
TreeNode *right;
TreeNode *parent;
int val;
};
class BinaryTree{
public:
BinaryTree(int rootValue);
~BinaryTree();
bool insertNodeWithValue(int value);
bool deleteNodeWithValue(int value);
void printTree();
private:
TreeNode *root;
};
5.通常所说的堆是二叉堆,是完全二叉树。对于下标为i的节点,其父节点为(int)i/2,其左子节点为2i,右子节点为2i+1.
图
1.广度优先:优先访问其所有邻近节点,在访问其他节点。即。对于任意节点,算法首先发现距离为d的节点,当所有距离为d的节点都被访问后,算法才会访问距离为d+1的节点;深度优先:对于某个节点v,如果它有未搜索的边,则沿着这条边继续搜索下去,直到该路径无法发现新的节点,回溯回节点v,继续搜索它的下一条边。
2.Dijkstra的核心在于,利用贪心的思想,在剩下的节点中选取离源点最近的那个加入集合,并且更新其邻近节点到源点的距离,直至所有节点都被加入集合。
3.Floyd算法的核心是动态规划,利用二维矩阵存储i,j之间的最短距离,矩阵的初始值为i,j的权值,如果i,j不直接相连,则值为正无穷。
4. BFS vs DFS的讨论。
BFS:这是一种基于队列这种数据结构的搜索方式,它的特点是由每一个状态可以扩展出许多状态,然后再以此扩展,直到找到目标状态或者队列中头尾指针相遇,即队列中所有状态都已处理完毕。DFS:基于递归的搜索方式,它的特点是由一个状态拓展一个状态,然后不停拓展,直到找到目标或者无法继续拓展结束一个状态的递归。
DFS遍历:树的中序遍历、前序遍历和后序遍历
void preOrderTraversal(TreeNode *root){
if(!root){
return;
}
visit(root);
preOrderTraversal(root->left);
preOrderTraversal(root->right);
}
void inOrderTraversal(TreeNode *root){
if(!root){
return ;
}
inOrderTraversal(root->right);
visit(root);
inOrderTraversal(root->left);
}
void postOrderTraversal(TreeNode *root){
if(!root){
return;
}
postOrderTraversal(root->left);
postOrderTraversal(root->right);
visit(root);
}
BFS遍历:
void levelTraversal(TreeNode *root){
queue<TreeNode *> nodeQueue;
TreeNode *currentNode;
if(!root){
return;
}
nodeQueue.push(root);
while(!nodeQueue.empty()){
currentNode = nodeQueue.front();
processNode = nodeQueue.front();
processNode(currentNode);
if(currentNode->left){
nodeQueue.push(currentNode->left);
}
if(currentNode->right){
nodeQueue.push(currentNode->right);
}
nodeQueue.pop()
}
}