2013.4.7notes

来源:互联网 发布:java自带的md5加密 编辑:程序博客网 时间:2024/06/03 20:44

今天是清明放假回来第一天,上周日的课程,但早晨起来匆匆忙忙以为是周一,赶来上算法分析,结果白跑一趟.索性既来之则安之”,找个教室自己看看书,顺便准备一下面试.

 

动态规划:

与之前方法的不同:

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的搜索是最基础的

 

 

 

 

 

 

堆与优先队列

最小值堆:{K0K1K2…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)

堆是优先队列的一种自然实现方法。

原创粉丝点击