1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 北邮22信通:二叉树各种遍历所有常见算法汇总

北邮22信通:二叉树各种遍历所有常见算法汇总

时间:2019-11-10 10:58:40

相关推荐

北邮22信通:二叉树各种遍历所有常见算法汇总

北邮22信通一枚~

跟随课程进度每周更新数据结构与算法的代码和文章

持续关注作者 解锁更多邮苑信通专属代码~

获取更多文章 请访问专栏~

北邮22信通_青山如墨雨如画的博客-CSDN博客

目录

1.二叉树的前序遍历

1.1递归算法

1.2非递归算法

1.2.1模板类实现栈

1.2.2模板类实现栈的优化算法

1.2.3 STL栈

2.二叉树的中序遍历

2.1递归算法

2.2非递归算法

2.2.1模板类实现栈

2.2.2模板类实现栈的优化算法

2.2.3 STL栈

3.二叉树的后序遍历

3.1递归算法

3.2非递归算法

3.3说明

4.层序遍历

5.模板类实现栈完整代码

5.1代码部分

5.2运行结果

6.STL实现栈完整代码

6.1代码部分

6.2运行结果:

1.二叉树的前序遍历

1.1递归算法

template<class temp>void bintree<temp>::preorder(binnode<temp>* r){if (r != NULL){cout << r->data;preorder(r->leftchild);preorder(r->rightchild);}}

1.2非递归算法

1.2.1模板类实现栈

栈顶元素永远为当前元素的父节点,设r为当前访问的节点,则

1.若r!=NULL,访问r(cout<<s[top].r->data;)并入栈(s[++top].r=r;),调用r=r->leftchild;将r标记为1(s[top].tag=1;)返回1;

2.若r==NULL,重新设r为栈顶元素

2.1若r标记为2,说明右子树返回;r出栈,重新设r为栈顶元素(top--;),返回2.1;

2.2若r标记为1,说明左子树返回;调用r=r->rightchild;将r标记为2(s[top].tag=2;),返回1;

反复执行,直到栈空(top==-1),程序结束。

if(r!=NULL)

{

cout<<r->data;入栈

}

if(r==NULL)

1.不出栈,换右支

2.出栈

template<class temp>void bintree<temp>::stackpreorder(binnode<temp>* r){linkstack<temp> s[100];//栈int top = -1;//栈顶指针do{while (r != NULL)//入栈并访问,设置为左子树{s[++top].r = r;s[top].tag = 1;cout << s[top].r->data;r = r->leftchild;}while ((top != -1) && s[top].tag == 2)//出栈top--;if ((top != -1) && (s[top].tag == 1)){//设置栈顶访问右子树r = s[top].r->rightchild;s[top].tag = 2;}} while (top != -1);}

1.2.2模板类实现栈的优化算法

当前节点,访问完其左子树之后,依靠当前结点找到右子树,之后当前节点不再提供信息,等待出栈;可以提前让当前结点出栈,简化递归过程。

算法优化:

if(r!=NULL)

{

cout<<r->data;入栈

}

if(R==NULL)

出栈,换右支

template<class temp>void bintree<temp>::quickstackpreorder(binnode<temp>* r){linkstack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){cout << r->data;s.push(r);r = r->leftchild;}else{r = s.pop();r = r->rightchild;}}}

1.2.3 STL栈

template<class temp>void bintree<temp>::quickSTLpreorder(binnode<temp>* r){stack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){cout << r->data;s.push(r);r = r->leftchild;}else{r = s.top();s.pop();r = r->rightchild;}}}

2.二叉树的中序遍历

2.1递归算法

template<class temp>void bintree<temp>::inorder(binnode<temp>* r){if (r != NULL){inorder(r->leftchild);cout << r->data;inorder(r->rightchild);}}

2.2非递归算法

2.2.1模板类实现栈

栈顶元素永远为当前元素的父节点,设r为当前访问的节点,则

1.若r!=NULL,r入栈(s[++top].r=r;),调用r=r->leftchild;将r标记为1(s[top].tag=1;),返回1;

2.若r==NULL,重新设r为栈顶元素

2.1若r标记为2,说明右子树返回;r出栈,重新设r为栈顶元素(top--;),返回2.1;

2.2若r标记为1,说明左子树返回;调用r=r->rightchild;访问r(cout<<s[top].r->data;)并将r标记为2(s[top].tag=2;),返回1;

反复执行,直到栈空(top==-1),程序结束。

if(r!=NULL)

{

入栈;

}

if(r==NULL)

1:cout<<r->data;不出栈,换右支;

2:出栈

template<class temp>void bintree<temp>::stackinorder(binnode<temp>* r){linkstack<temp> s[100];int top = -1;do{while (r != NULL){s[++top].r = r;s[top].tag = 1;r = r->leftchild;}while ((top != -1) && (s[top].tag == 2))top--;if ((top != -1) && (s[top].tag == 1)){r = s[top].r->rightchild;cout << s[top].r->data;s[top].tag = 2;}} while (top != -1);}

2.2.2模板类实现栈的优化算法

当前节点,访问完其左子树之后,依靠当前结点找到右子树,之后当前节点不再提供信息,等待出栈;可以提前让当前结点出栈,简化递归过程。

算法优化

if(r!=NULL)

{

入栈;

}

if(r==NULL)

{

cout<<r->data;

出栈,换右支;

}

template<class temp>void bintree<temp>::quickstackinorder(binnode<temp>* r){linkstack<binnode<temp>*>s;while (!s.empty() || r != NULL){if (r != NULL){s.push(r);r = r->leftchild;}else{r = s.pop();cout << r->data;r = r->rightchild;}}}

2.2.3 STL栈

template<class temp>void bintree<temp>::quickSTLinorder(binnode<temp>* r){stack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){s.push(r);r = r->leftchild;}else{r = s.top();s.pop();cout << r->data;r = r->rightchild;}}}

3.二叉树的后序遍历

3.1递归算法

template<class temp>void bintree<temp>::postorder(binnode<temp>* r){if (r != NULL){postorder(r->leftchild);postorder(r->rightchild);cout << r->data;}}

3.2非递归算法

栈顶元素永远为当前元素的父节点,设r为当前访问的节点,则

1.若r!=NULL,r入栈(s[++top].r=r;),调用r=r->leftchild;将r标记为1(s[top].tag=1;),返回1;

2.若r==NULL,重新设r为栈顶元素

2.1若r标记为2,说明右子树返回;访问r(cout<<s[top].r->data;)r出栈,重新设r为栈顶元素(top--;),返回2.1;

2.2若r标记为1,说明左子树返回;调用r=r->rightchild;将r标记为2(s[top].tag=2;),返回1;

反复执行,直到栈空(top==-1),程序结束。

if(r!=NULL)

{

入栈;

}

if(r==NULL)

1:不出栈,换右支;

2:cout<<r->data;出栈

template<class temp>void bintree<temp>::stackpostorder(binnode<temp>* r){linkstack<temp> s[100];int top = -1;do{while (r != NULL){s[++top].r = r;s[top].tag = 1;r = r->leftchild;}while ((top != -1) && (s[top].tag == 2)){cout << s[top].r->data;top--;}if ((top != -1) && (s[top].tag == 1)){r = s[top].r->rightchild;s[top].tag = 2;}} while (top != -1);}

3.3说明

非递归遍历的优化算法核心是:因为根节点的作用是索引左子树,所以访问完左子树之后根节点就没有意义了,所以可以跳过根节点直接访问右子树,从而减小了时间复杂度。但是在后序遍历中,根节点最后访问,所以没有相应的优化算法。

4.层序遍历

层序遍历请看这篇文章 有详细讲解~

北邮22信通:二叉树层序遍历的两种方法&&首发模板类交互_青山如墨雨如画的博客-CSDN博客

5.模板类实现栈完整代码

下面给出模板类实现栈的完整代码。

5.1代码部分

#include<iostream>using namespace std;#define MAXSIZE 100005class student{private:int ID;string name;public:int existence;student(){this->ID = 0;this->name = "unknown name";this->existence = 0;}student(int ID, string name){this->ID = ID;this->name = name;this->existence = 1;}friend ostream& operator<<(ostream& output, student& s){output << s.ID << " " << s.name << endl;return output;}};template<class temp>struct binnode;//栈template <class temp>struct node{temp data;node<temp>* next;};template <class temp>class linkstack{public:binnode<temp>* r;int tag;linkstack() { top = NULL; }~linkstack();void push(temp x);temp pop();temp gettop();bool empty(){return top == NULL ? true : false;}private:node<temp>* top;};template <class temp>void linkstack<temp>::push(temp x){node<temp>* p = new node<temp>;p->data = x;p->next = this->top;this->top = p;}template<class temp>temp linkstack<temp>::pop(){if (empty())throw "下溢";temp x = this->top->data;node<temp>* p = this->top;this->top = this->top->next;delete p;return x;}template<class temp>linkstack<temp>::~linkstack(){while (this->top != NULL){node<temp>* p = this->top;this->top = this->top->next;delete p;}}template<class temp>temp linkstack<temp>::gettop(){if (empty())throw"下溢";return this->top->data;}//二叉树template<class temp>struct binnode{temp data;binnode<temp>* leftchild;binnode<temp>* rightchild;};template<class temp>class bintree{private:void create(binnode<temp>*& r, temp data[], int i, int n);void release(binnode<temp>* r);public:binnode<temp>* root;bintree(temp data[], int n);void preorder(binnode<temp>* r);void stackpreorder(binnode<temp>* r);void quickstackpreorder(binnode<temp>* r);void inorder(binnode<temp>* r);void stackinorder(binnode<temp>* r);void quickstackinorder(binnode<temp>* r);void postorder(binnode<temp>* r);void stackpostorder(binnode<temp>* r);void levelorder(binnode<temp>* r);~bintree();};template<class temp>void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n){if (i <= n && data[i - 1].existence != 0){r = new binnode<temp>;r->data = data[i - 1];r->leftchild = r->rightchild = NULL;create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/}}template<class temp>bintree<temp>::bintree(temp data[], int n){create(this->root, data, 1, n);}template<class temp>void bintree<temp>::preorder(binnode<temp>* r){if (r != NULL){cout << r->data;preorder(r->leftchild);preorder(r->rightchild);}}template<class temp>void bintree<temp>::stackpreorder(binnode<temp>* r){linkstack<temp> s[100];int top = -1;do{while (r != NULL){s[++top].r = r;s[top].tag = 1;cout << s[top].r->data;r = r->leftchild;}while ((top != -1) && s[top].tag == 2)top--;if ((top != -1) && (s[top].tag == 1)){r = s[top].r->rightchild;s[top].tag = 2;}} while (top != -1);}template<class temp>void bintree<temp>::quickstackpreorder(binnode<temp>* r){linkstack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){cout << r->data;s.push(r);r = r->leftchild;}else{r = s.pop();r = r->rightchild;}}}template<class temp>void bintree<temp>::inorder(binnode<temp>* r){if (r != NULL){inorder(r->leftchild);cout << r->data;inorder(r->rightchild);}}template<class temp>void bintree<temp>::stackinorder(binnode<temp>* r){linkstack<temp> s[100];int top = -1;do{while (r != NULL){s[++top].r = r;s[top].tag = 1;r = r->leftchild;}while ((top != -1) && (s[top].tag == 2))top--;if ((top != -1) && (s[top].tag == 1)){r = s[top].r->rightchild;cout << s[top].r->data;s[top].tag = 2;}} while (top != -1);}template<class temp>void bintree<temp>::quickstackinorder(binnode<temp>* r){linkstack<binnode<temp>*>s;while (!s.empty() || r != NULL){if (r != NULL){s.push(r);r = r->leftchild;}else{r = s.pop();cout << r->data;r = r->rightchild;}}}template<class temp>void bintree<temp>::postorder(binnode<temp>* r){if (r != NULL){postorder(r->leftchild);postorder(r->rightchild);cout << r->data;}}template<class temp>void bintree<temp>::stackpostorder(binnode<temp>* r){linkstack<temp> s[100];int top = -1;do{while (r != NULL){s[++top].r = r;s[top].tag = 1;r = r->leftchild;}while ((top != -1) && (s[top].tag == 2)){cout << s[top].r->data;top--;}if ((top != -1) && (s[top].tag == 1)){r = s[top].r->rightchild;s[top].tag = 2;}} while (top != -1);}template<class temp>void bintree<temp>::levelorder(binnode<temp>* R){binnode<temp>* queue[MAXSIZE];int f = 0, r = 0;if (R != NULL)queue[++r] = R;//根节点入队while (f != r){binnode<temp>* p = queue[++f];//队头元素入队cout << p->data;//出队打印if (p->leftchild != NULL)queue[++r] = p->leftchild;//左孩子入队if (p->rightchild != NULL)queue[++r] = p->rightchild;//右孩子入队}}template <class temp>void bintree<temp>::release(binnode<temp>* r){if (r != NULL){release(r->leftchild);release(r->rightchild);delete r;}}template<class temp>bintree<temp>::~bintree(){release(this->root);}int main(){system("color 0A");student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };bintree<student>bintreee(stu, 5);cout << "前序遍历:" << endl;bintreee.preorder(bintreee.root);cout << endl << "模板类实现栈前序遍历:" << endl;bintreee.stackpreorder(bintreee.root);cout << endl << "栈快排前序遍历:" << endl;bintreee.quickstackpreorder(bintreee.root);cout << endl << "中序遍历:" << endl;bintreee.inorder(bintreee.root);cout << endl << "模板类实现栈中序遍历:" << endl;bintreee.stackinorder(bintreee.root);cout << endl << "栈快排中序遍历" << endl;bintreee.quickstackinorder(bintreee.root);cout << endl << "后序遍历:" << endl;bintreee.postorder(bintreee.root);cout << endl << "模板类实现栈后序遍历:" << endl;bintreee.stackpostorder(bintreee.root);cout << endl << "层序遍历:" << endl;bintreee.levelorder(bintreee.root);cout << endl;return 0;}

5.2运行结果

5.2.1代码效果图:

5.2.2运行结果:

6.STL实现栈完整代码

6.1代码部分

#include<iostream>#include<stack>using namespace std;#define MAXSIZE 100005class student{private:int ID;string name;public:int existence;student(){this->ID = 0;this->name = "unknown name";this->existence = 0;}student(int ID, string name){this->ID = ID;this->name = name;this->existence = 1;}friend ostream& operator<<(ostream& output, student& s){output << s.ID << " " << s.name << endl;return output;}};//二叉树template<class temp>struct binnode{temp data;binnode<temp>* leftchild;binnode<temp>* rightchild;};template<class temp>class bintree{private:void create(binnode<temp>*& r, temp data[], int i, int n);void release(binnode<temp>* r);public:binnode<temp>* root;bintree(temp data[], int n);void preorder(binnode<temp>* r);void quickSTLpreorder(binnode<temp>* r);void inorder(binnode<temp>* r);void quickSTLinorder(binnode<temp>* r);void postorder(binnode<temp>* r);void levelorder(binnode<temp>* r);~bintree();};template<class temp>void bintree<temp>::create(binnode<temp>*& r, temp data[], int i, int n){if (i <= n && data[i - 1].existence != 0){r = new binnode<temp>;r->data = data[i - 1];r->leftchild = r->rightchild = NULL;create(r->leftchild, data, 2 * i, n);/*书上代码错误1:向函数传入实参时少传入一个n*/create(r->rightchild, data, 2 * i + 1, n);/*书上代码错误同上*/}}template<class temp>bintree<temp>::bintree(temp data[], int n){create(this->root, data, 1, n);}template<class temp>void bintree<temp>::preorder(binnode<temp>* r){if (r != NULL){cout << r->data;preorder(r->leftchild);preorder(r->rightchild);}}template<class temp>void bintree<temp>::quickSTLpreorder(binnode<temp>* r){stack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){cout << r->data;s.push(r);r = r->leftchild;}else{r = s.top();s.pop();r = r->rightchild;}}}template<class temp>void bintree<temp>::inorder(binnode<temp>* r){if (r != NULL){inorder(r->leftchild);cout << r->data;inorder(r->rightchild);}}template<class temp>void bintree<temp>::quickSTLinorder(binnode<temp>* r){stack<binnode<temp>*>s;while (!s.empty() || (r != NULL)){if (r != NULL){s.push(r);r = r->leftchild;}else{r = s.top();s.pop();cout << r->data;r = r->rightchild;}}}template<class temp>void bintree<temp>::postorder(binnode<temp>* r){if (r != NULL){postorder(r->leftchild);postorder(r->rightchild);cout << r->data;}}template<class temp>void bintree<temp>::levelorder(binnode<temp>* R){binnode<temp>* queue[MAXSIZE];int f = 0, r = 0;if (R != NULL)queue[++r] = R;//根节点入队while (f != r){binnode<temp>* p = queue[++f];//队头元素入队cout << p->data;//出队打印if (p->leftchild != NULL)queue[++r] = p->leftchild;//左孩子入队if (p->rightchild != NULL)queue[++r] = p->rightchild;//右孩子入队}}template <class temp>void bintree<temp>::release(binnode<temp>* r){if (r != NULL){release(r->leftchild);release(r->rightchild);delete r;}}template<class temp>bintree<temp>::~bintree(){release(this->root);}int main(){system("color 0A");student stu[5] = { {1,"zhang"},{2,"wang"},{3,"li"},{4,"zhao"},{5,"liu"} };bintree<student>bintreee(stu, 5);cout << "前序遍历:" << endl;bintreee.preorder(bintreee.root);cout << endl << "STL前序遍历:" << endl;bintreee.quickSTLpreorder(bintreee.root);cout << endl << "中序遍历:" << endl;bintreee.inorder(bintreee.root);cout << endl << "STL中序遍历" << endl;bintreee.quickSTLinorder(bintreee.root);cout << endl << "后序遍历:" << endl;bintreee.postorder(bintreee.root);cout << endl << "层序遍历:" << endl;bintreee.levelorder(bintreee.root);cout << endl;return 0;}

6.2运行结果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。