今天是清明放假回来第一天,上周日的课程,但早晨起来匆匆忙忙以为是周一,赶来上算法分析,结果白跑一趟.索性”既来之则安之”,找个教室自己看看书,顺便准备一下面试.
动态规划:
与之前方法的不同:
1. 贪心法是依赖于已经求解出的子问题,所以是自顶向下的
2. 分治法,各个子问题是独立的,自上而下
3. 动归子问题不独立,利用空间复杂度换取时间复杂度
动态规划三要素:
1. 最优子结构
2. 子问题重叠
3. 自底向上解决
两个例子:
1. lls
2. 0-1背包
周游二叉树:
递归深度优先周游
1. 前序中序后序
Template<classT>
Void BinaryTree<T>::DepthOrder(BinaryTreeNode<T>* root){
If(root!=null){
Visit(root);
DepthOrder(root->leftchild());
Visit(root);
DepthOrder(root->rightchild());
Visit(root);
}
}
发现强项优势,不同于别人的地方。
非递归深度优先周游(利用栈)
利用栈记下尚待周游的结点或子树,以备以后访问。
1. 前序周游
遇到结点,访问。并把此结点入栈,然后下降去周游它的左子树
周游完左子树,从栈顶弹出元素结点,并按照他的右链接指示的地址再去周游右子树
Template<classT>
Void BinaryTree<T>::DepthOrderWithout(BinaryTreeNode<T>* root){
Stack<BinaryTreeNode<T>*>aStack;
BinaryTreeNode<T>*pointer = root;
While(!aStack.empty()||pointer){
If(pointer){
Visit(pointer->value());
aStack.push(pointer);
pointer =pointer->leftchild;
}
else{
pointer = aStack.top();
aStack.pop();
pointer = pointer->rightchild;
}
}// end while
}
2. 中序周游
根结点入栈,左子树周游,当左为空,弹出一个,访问。然后周游右子树
Template<classT>
Void BinaryTree<T>::DepthOrderWithout(BinaryTreeNode<T>* root){
Stack<BinaryTreeNode<T>*>aStack;
BinaryTreeNode<T>*pointer = root;
While(!aStack.empty()||pointer){
If(pointer){
aStack.push(pointer);
pointer =pointer->leftchild;
}
else{
pointer = aStack.top();
aStack.pop();
Visit(pointer->value());
pointer = pointer->rightchild;
}
}// end while
}
3. 后序周游
遇到一个结点,推入栈,周游左子树。
周游结束后,不能访问处于栈顶的结点,弹出来,周游右子树,再根结点入栈。
Enum Tags{Left,Right};
Template<classT>
Void BinaryTree<T>::DepthOrderWithout(BinaryTreeNode<T>* root){
Stack<BinaryTreeNode<T>*>aStack;
BinaryTreeNode<T>*pointer = root;
While(1){
While(pointer!=null){
Element.pointer = pointer;
Element.tag = left;
aStack.push(element);
}
Element =aStack.top();
aStack.pop();
pointer =element.pointer;
while(element.tag ==Right){
Visit(pointer->value());
If(aStack.empty(){
Return;
}
Else{
Element = aStack.top();
aStack.pop();
pointer=element.pointer;
}
}
Element.tag = left;
aStack.push(element);
pointer=pointer->rightchild();
}//while end
}
穿线二叉树
二叉搜索树
可以是空树
左子树小于根节点
右子树大于根节点
性质:按照中序周游将各节点打印,得到按小到大的排序
二叉搜索树的效率就在于只需要检索二个子树之一
效率logn
二叉搜索树的增加、删除(算法实现)
组织索引,内存中重要的树形索引。BST的搜索是最基础的
堆与优先队列
最小值堆:{K0,K1,K2…Kn-1}有如下性质:
Ki<=K2i+1
Ki<=K2i+2
根节点小于左右子树,也小于剩下所有
建堆过程:
将关键码放入一维数组,形成完全二叉树
。。。
Template<class T>
Class MinHeap
{
Private:
T * heapArray;
Int CurrentSize;
Int MaxSize;
Void BuildHeap();
Public:
Bool isLeaf(int pos)const;
…
//增删查改
T & RemoveMin();
}
筛选法-建堆
Void MinHeap<T>::BuildHeap()
{
For(inti=Currentsize/2-1;i>=0;--i){
SiftDown(i);
}
}
Void MinHeap<T>::SiftDown(intposition){
…
}
建堆效率:O(n)
插入删除元素的平均和最差时间代价是O(logn)
堆是优先队列的一种自然实现方法。