二叉树的递归非递归遍历

来源:互联网 发布:网络关于长者的段子 编辑:程序博客网 时间:2024/05/16 00:45

二叉树(BinaryTree)是n(n≥0)个结点的有限集,它或者是空集(n=0),或者由一个根结点及两棵互不相交的、分别称作这个根的左子树和右子树的二叉树组成。

二叉树的递归遍历很简单,根据其递归定义直接可以编码,如下:

1.递归前序遍历

void PreOrder(BtNode *ptr)
{
if(ptr != NULL)
{
cout << ptr->data << " ";
PreOrder(ptr->leftchild);
PreOrder(ptr->rigthchild);
}
}

2.递归中序遍历
void InOrder(BtNode *ptr)
{
if(ptr != NULL)
{
InOrder(ptr->leftchild);
cout << ptr->data << " ";
InOrder(ptr->rigthchild);
}
}

3.递归后序遍历

void PastOrder(BtNode *ptr)
{
if(ptr != NULL)
{
PastOrder(ptr->leftchild);
PastOrder(ptr->rigthchild);
cout << ptr->data << " ";
}
}


对于非递归遍历的话,可以使用栈操作,也可以不使用栈直接加一个标记(标记某节点是第次入栈)原理同栈一样

下面程序使用栈来操作,所需栈操作如下:

template<class Type>
class Stack
{
private:
Type *data;
int maxsize;
int top;
Stack(const Stack<Type> &);
Stack<Type> &operator=(const Stack<Type> &);
public:
Stack(int sz = STACKSIZE) :top(-1)
{
maxsize = sz > STACKSIZE ? sz : STACKSIZE;
data = (Type*)malloc(sizeof(Type)*maxsize);
}

        ~Stack()
{
free(data); //important,cause alloc memory in constructor
data = NULL;
maxsize = 0;
top = -1;
}
int size() const { return top + 1; }
bool empty() const { return size() == 0; }
bool full() const { return size() == maxsize; }
bool push(const Type &x)
{
if(full())
{
return false;
}
data[++top] = x;
return true;
}

        bool pop(Type &x)

{
if(empty())
return false;
x = data[top--];
return true;
}
bool gettop(Type &x)
{
if(empty())
return false;
x = data[top];
return true;
}
};

1.1非递归前序遍历

void NicePreOrder(BtNode *ptr)
{
if(ptr == NULL) return;
Stack<BtNode *>st;


while(ptr != NULL || !st.empty())
{
while(ptr != NULL)
{
cout << ptr->data << " ";
st.push(ptr);
ptr = ptr->leftchild;
}
st.pop(ptr);
ptr = ptr->rigthchild;
}
}

1.2非递归中序遍历

void NiceInOrder(BtNode *ptr)
{
if(ptr == NULL) return;
Stack<BtNode *> st;


while(ptr != NULL || !st.empty())
{
while(ptr != NULL)
{
st.push(ptr);
ptr = ptr->leftchild;
}
st.pop(ptr);
cout << ptr->data << " ";
ptr = ptr->rigthchild;
}
}

其中非递归后序遍历是最难的,出父节点时首先要看其左右子节点是否遍历

1.3非递归后序遍历

void NicePastOrder(BtNode *ptr)
{
if(ptr == NULL) return;
Stack<BtNode *> st;
BtNode *pb = NULL;                                                                                        //标记刚才访问过的节点

st.push(ptr);

while(ptr != NULL || !st.empty())
{
if(st.empty())                                                                                             //栈空时即表示全部访问过了,作为退出
break;
else if(!st.empty())
st.gettop(ptr);


//如果pb为空,则直接插入后续元素,否则,看其左右是否均已访问过
while(ptr != NULL && (pb == NULL || ptr->rigthchild != pb))                    //左右还没有访问完
{
if(ptr->leftchild == NULL || (pb != NULL && pb == ptr->leftchild))    //左边已访问过
{
ptr = ptr->rigthchild;
}
else//左边没有访问过
{
ptr = ptr->leftchild;
}
if(ptr != NULL)
st.push(ptr);
}//该循环退出即表示访问到了叶子节点

st.gettop(ptr);
if(ptr->rigthchild != NULL && ptr->rigthchild != pb)                                  //看其右边是否存在并且访问过
{
ptr = ptr->rigthchild;
continue;
}


st.pop(ptr);
pb = ptr;
cout << ptr->data << " ";
}
}

0 0
原创粉丝点击