二叉树的建立、销毁、各种遍历(递归、非递归)
二叉树的基本操作,都使用递归:
//二叉树 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; } } }