您的位置:首页 > 其它

二叉树的建立、销毁、各种遍历(递归、非递归)

2012-05-05 10:51 423 查看
二叉树的基本操作,都使用递归:

//二叉树
class Node
{
public:
char data;
Node *left;
Node *right;
Node():data(' '),left(NULL),right(NULL){}
Node(char ch):data(ch),left(NULL),right(NULL){}
};

//广义表建立二叉树,输入:A(B(D,E(G,)),C(,F))*
void CreateBinTree(Node* & Root,char *str)
{
stack<Node*> s;
Root=NULL;
Node* p=NULL,*t=NULL;
int k,i=0;
while(str[i])
{
switch(str[i])
{
case '(': s.push(p); k=1; break;
case ')': t=s.top(); s.pop(); break;
case ',': k=2; break;
default:
p=new Node(str[i]);
if(Root==NULL) Root=p;
else if(k==1)
{
t=s.top(); t->left=p;
}
else
{
t=s.top(); t->right=p;
}
}
++i;
}
}

//递归先序遍历
void preOrderTraverse(Node *p)
{
if(p != NULL)
{
cout<<p->data;
preOrderTraverse(p->left);
preOrderTraverse(p->right);
}
}

//求节点个数
int Size(Node* root)
{
if(root == NULL) return 0;
return 1 + Size(root->left) + Size(root->right);
}

//求树的高度
int TreeDepth(Node* t)
{
int hl,hr,h;
if(t != NULL)
{
hl = TreeDepth(t->left);
hr = TreeDepth(t->right);
h = hl>hr? hl:hr;
return h+1;
}
return 0;
}

//销毁二叉树
void freeTree(Node*& p)
{
if(p->left != NULL)
freeTree(p->left);
if(p->right != NULL)
freeTree(p->right);
delete(p);
}


二叉树的各种遍历:

//输出第level层的所有节点(从左到右),成功返回1
int PrintNodeAtLevel(Node* root,int level)
{
if(!root || level<0)  return 0;
if(level==0)
{
cout<<root->data<<" ";
return 1;
}
return PrintNodeAtLevel(root->left,level-1)+PrintNodeAtLevel(root->right,level-1);
}

//层次遍历二叉树,使用树的高度
void PrintNodeByLevel(Node* root,int depth)
{
for(int level=0; level<depth; level++)
{
PrintNodeAtLevel(root,level);
cout<<endl;
}
}
//层次遍历二叉树,不使用树的高度
void PrintNodeByLevel(Node* root)
{
for(int level=0; ;level++)
{
if(!PrintNodeAtLevel(root,level)) break;
cout<<endl;
}
}

/*层次遍历树算法:
(1)初始化队列为空
(2)若二叉树为空,直接返回
(3)将根节点指针放到队列中
(4)若队列非空,则重复以下操作:
1.队头元素出队并访问该元素
2.若该节点左孩子非空,则左孩子节点指针入队
3.若该节点右孩子非空,则右孩子节点指针入队
*/
void layerOrder(Node* t)//层次遍历树
{
queue<Node*> q;
if(t==NULL) return;
q.push(t);
while(!q.empty())
{
Node* p=q.front();
q.pop();
cout<<p->data<<" ";
if(p->left) q.push(p->left);
if(p->right) q.push(p->right);
}
}

//层次遍历二叉树
void LevelOrder(Node* root)
{
if(root==NULL) return;
vector<Node*> v;
v.push_back(root);
int cur=0;
int last=1;
while(cur<v.size())
{
last=v.size();
while(cur<last)
{
cout<<v[cur]->data<<" ";
if(v[cur]->left) v.push_back(v[cur]->left);
if(v[cur]->right) v.push_back(v[cur]->right);
cur++;
}
cout<<endl;
}
}

//非递归先序遍历树
void preOrder(Node* root)
{
stack<Node*> s;
Node* p=NULL;
if(root==NULL) return;
s.push(root);
while(!s.empty())
{
p=s.top(); s.pop();
cout<<p->data<<" ";
if(p->right) s.push(p->right);
if(p->left) s.push(p->left);
}
}

//非递归先序遍历树
void preOrder(Node* t)
{
stack<Node*> s;
Node* p=t;
while (p!=NULL || !s.empty())
{
while (p!=NULL)  //遍历左子树
{
cout<<p->data<<" ";
s.push(p);
p=p->left;
}
if (!s.empty()) //通过下一次循环中的内嵌while实现右子树遍历
{
p=s.top();
s.pop();
p=p->right;
}
}
}

/*非递归中序遍历树算法:从根节点开始,只要当前节点存在,或者栈不为空,则重复下面操作:
(1)如果当前节点存在,则进栈并走左子树。
(2)否则退栈并访问,然后走右子树。
*/
void inOrder(Node* t)
{
stack<Node*> s;
Node* p=t;
while(p||!s.empty())
{
if(p)
{
s.push(p);
p=p->left;
}
else
{
p=s.top();s.pop();
cout<<p->data<<" ";
p=p->right;
}
}
}

/*非递归后序遍历树:后序遍历,先遍历到的结点最后访问
用两个栈,一个栈用来遍历,另一个栈保存遍历到的结点,最后一起出栈,就是后序遍历结果
*/
void postOrder(Node* root)
{
stack<Node*> sTraverse,sVisit;
Node* p=NULL;
if(root==NULL) return;
sTraverse.push(root);
while(!sTraverse.empty())
{
p=sTraverse.top(); sTraverse.pop();
sVisit.push(p);
if(p->left) sTraverse.push(p->left);
if(p->right) sTraverse.push(p->right);
}
while(!sVisit.empty())
{
p=sVisit.top(); sVisit.pop();
cout<<p->data<<" ";
}
}

/*非递归后序遍历树算法:从根节点开始,只要当前节点存在,或者栈不为空,则重复下面操作:
(1)从当前节点开始,进栈并走左子树,直到左子树为空。
(2)如果栈顶节点的右子树为空,或者栈顶节点的右孩子为刚访问过的节点,
则退栈并访问,然后置当前节点指针为空。
(3)否则走右子树。
*/
void postOrder(Node* t)
{
Node *p,*q;
stack<Node*> s;
p=t;
q=NULL;
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p); p=p->left;
}
if(!s.empty())
{
p=s.top();
if((p->right==NULL) || (p->right==q))
{
cout<<p->data<<" ";
q=p;
s.pop();
p=NULL;
}
else p=p->right;
}
}
}

/*根节点到r节点的路径:
后序遍历时访问到r节点时,栈中的所有的节点均为r节点的祖先,这些祖先构成根节点到r节点的路径
*/
void nodePath(Node* root,Node* r)
{
Node *p,*q;
stack<Node*> s;
p=root;
q=NULL;   //q保存刚访问过的节点
while(p!=NULL||!s.empty())
{
while(p!=NULL)
{
s.push(p); p=p->left;
}
if(!s.empty())
{
p=s.top();
if( (p->right==NULL) || (p->right==q) )
{
if(p==r)
{
while(!s.empty())
{
Node* t=s.top();
s.pop();
cout<<t->value<<" ";
}
return;
}
else
{
q=p;
s.pop();
p=NULL;
}
}
else p=p->right;
}
}
}


判断二叉树是否平衡、是否完全二叉树、是否二叉排序树

/article/8456290.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: