1 非递归前序周游二叉树
思想:
遇到一个结点,就访问该结点,并把此结点的非空右结点推入栈中,然后下降去周游它的左子树;
周游完左子树后,从栈顶托出一个结点,并按照它的右链接指示的地址再去周游该结点的右子树结构。
普通版
template<class T> void BinaryTree<T>::PreOrderWithoutRecusion
(BinaryTreeNode<T>* root)
//非递归前序遍历二叉树或其子树
{
using std::stack; //使用STL中的stack
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();}
}
}
简化版
template<class T> void BinaryTree<T>::PreOrderWithoutRecusion
(BinaryTreeNode<T>* root)
//非递归前序遍历二叉树或其子树
{
using std::stack; //使用STL中的stack
stack<BinaryTreeNode<T>* > aStack;
BinaryTreeNode<T>* pointer=root;
aStack.push(NULL); // 栈底监视哨
while(pointer){ // 或者!aStack.empty()
Visit(pointer->value()); //访问当前结点
if (pointer->rightchild() != NULL) //右孩子入栈
aStack.push(pointer->rightchild());
if (pointer->leftchild() != NULL)
pointer = pointer->leftchild(); //左路下降
else { //左子树访问完毕,转向访问右子树
pointer=aStack.top();
aStack.pop(); //栈顶元素退栈 }
}
}
貌似普通版本是让所有结点入栈,简化的版本是只让右孩子入栈,我看不太懂,请高人指教。
2 广度优先周游二叉树
终于明白为什么用队列了。根结点入队,取队列首结点,访问当前结点,出队,左子树右子树入队。
3 用指针实现二叉树
在每个结点中除存储结点本身的数据外再设置两个指针字段llink和rlink,分别指向结点的左子女和右子女。
二叉链表表示的二叉树成员函数实现
其中有个判断左兄弟的
template<class T>
BinaryTreeNode<T>*BinaryTree<T>::LeftSibling
(BinaryTreeNode<T>* current)
{//返回current结点的左兄弟
if(current)//current不为空
{ //返回current结点的父结点
BinaryTreeNode<T>* temp=Parent(current);
//如果父结点为空,或者current没有左兄弟
If((temp==NULL)||current==temp->leftchild())
return NULL;
else return temp->leftchild(); }//end if
return NULL;
}
自己觉得用current=temp->leftchild() 来判断没有左兄弟很好!因为既然current是左孩子了,就不会有左兄弟了。
5 用数组实现完全二叉树
一些完全二叉树的公式