zoukankan      html  css  js  c++  java
  • 数据结构 树

      1 #include<iostream>
      2 #include<vector>
      3 #include<queue>
      4 #include<stack>
      5 using namespace std;
      6 struct node{
      7     int val;
      8     node *left, *right;
      9     bool vis;
     10     int tag;
     11 };
     12 
     13 void insert(node* &root, int val){
     14     if(root==NULL){
     15         root = new node;
     16         root->val = val;
     17         root->left=root->right=NULL;
     18         root->vis=true;
     19     }else{
     20         if(val<root->val) insert(root->left, val);
     21         else insert(root->right, val);
     22     }
     23 }
     24 
     25 void level(node* root){
     26     if(root==NULL) return;
     27     queue<node*> q;
     28     cout<<"level: ";
     29     q.push(root);
     30     while(q.size()){
     31         node* temp=q.front();
     32         q.pop();
     33         cout<<temp->val<<" ";
     34         if(temp->left) q.push(temp->left);
     35         if(temp->right) q.push(temp->right);
     36     }
     37     cout<<endl;
     38 }
     39 
     40 void reverselevel(node* root){
     41     //从下到上, 从右到左的层序遍历
     42     //可以发现和正常的层序遍历是相反的顺序, 可以把正常层序遍历的
     43     //的结果压栈,层序遍历结束之后,再出栈,就能得到结果
     44     //栈能很方便的得到反序序列
     45     queue<node*> q;
     46     stack<node*> ans;
     47     cout<<"reverselevel: ";
     48     q.push(root);
     49     while(q.size()){
     50         node* temp=q.front();
     51         q.pop();
     52         ans.push(temp);
     53         if(temp->left) q.push(temp->left);
     54         if(temp->right) q.push(temp->right);
     55     }
     56     while(ans.size()){
     57         cout<<ans.top()->val<<" ";
     58         ans.pop();
     59     }
     60     cout<<endl;
     61 }
     62 
     63 void preorder(node* root){
     64     stack<node*> s;
     65     node* p=root;
     66     cout<<"preorder: ";
     67     while(p || s.size()){
     68         if(p){
     69             cout<<p->val<<" ";
     70             s.push(p);
     71             p = p->left;
     72         }else{
     73             p = s.top();
     74             s.pop();
     75             p = p->right;
     76         }
     77     }
     78     cout<<endl;
     79 }
     80 
     81 void inorder(node* root){
     82     stack<node*> s;
     83     cout<<"inorder: ";
     84     node* p=root;
     85     while(s.size() || p){
     86         if(p){//一路访问到左下角
     87             s.push(p);
     88             p = p->left;
     89         }else{
     90             p = s.top();
     91             s.pop();
     92             cout<<p->val<<" ";
     93             p = p->right;
     94         }
     95     }
     96     cout<<endl;
     97 }
     98 
     99 void post(node* root){
    100     stack<node*> s;
    101     cout<<"post: ";
    102     node *p=root, *r=NULL;
    103     while(p || s.size()){
    104         if(p){
    105             s.push(p);
    106             p=p->left; //一路访问到左下角
    107         }else{
    108             //已经访问到最底部
    109             p=s.top();
    110             if(p->right && p->right!=r){//对右子树进行后续遍历
    111                 p=p->right;
    112                 s.push(p);
    113                 p=p->left;
    114             }else{//栈顶节点的右节点为空或者右节点已经访问
    115                 /*
    116                     左下角节点的右节点必定为空,访问该节点的值
    117                     让r记录最近访问的节点
    118                     为什么要把当前节点指向空指针呢? 为了能遍历右子树
    119                 */
    120                 p=s.top();
    121                 s.pop();
    122                 cout<<p->val<<" ";
    123                 r = p;
    124                 p=NULL;
    125             }
    126         }
    127     }
    128     cout<<endl;
    129 }
    130 
    131 //采用该方式进行后续遍历的时候, 栈中左右的节点均为当前节点的父节点
    132 void post1(node* root){
    133     cout<<"post1: ";
    134     stack<node*> s;
    135     s.push(root);
    136     node* temp=root;
    137     while(s.size()){
    138         if(temp->left && temp->left->vis) {
    139             s.push(temp->left);
    140             temp->left->vis=false;
    141             temp = temp->left;
    142             
    143         }
    144         else if(temp->right && temp->right->vis) {
    145             s.push(temp->right);
    146             temp->right->vis=false;
    147             temp = temp->right;
    148         }
    149         else{
    150             temp = s.top();
    151             s.pop();
    152             cout<<temp->val<<" ";
    153             temp = s.top();
    154         }
    155     }
    156     cout<<endl;
    157 }
    158 
    159 int h=-1;
    160 /*
    161     很巧妙的一个算法
    162     用last来记录每一层最后一个节点的位置, 当访问到该层的最后一个节点时,高度就加一
    163     怎么判断访问最后一个节点呢? 用front记录访问的位置, 当front==last就表示一层访问完成了;
    164     此外用rear表示队列中最后一个节点的位置, 当访问完上一层的所有节点的时候,rear一定指向的是当前层的
    165     最后一个节点的位置,把last更新为该位置
    166 */
    167 int height(node* root, int size){
    168     if(root==NULL) return 0;
    169     int front=-1, rear=-1;
    170     int last=0, level=0;
    171     vector<node*> q(size);
    172     q[++rear]=root;
    173     node *p;
    174     while(front<rear){
    175         p = q[++front];
    176         if(p->left) q[++rear] = p->left;
    177         if(p->right) q[++rear] = p->right;
    178         if(last==front){
    179             level++;
    180             last = rear;
    181         }
    182     }
    183     cout<<"height: "<<level<<endl;
    184     return level;
    185 }
    186 //二叉树中一定要先判断二叉树是否是空树
    187 //思路是如果有一个节点的左节点不存在,其后又出现叶子节点,那么一定不是完全二叉树
    188 bool isComplete(node* root){
    189     if(root==NULL) return root;
    190     queue<node*> q;
    191     q.push(root);
    192     bool exist_left=true;
    193     while(q.size()){
    194         node* temp=q.front();
    195         q.pop();
    196         if(temp->left){
    197             q.push(temp->left);
    198             if(!exist_left) return false;
    199         }else exist_left = false;
    200         if(temp->right){
    201             if(!exist_left) return false;
    202             q.push(temp->right);
    203         }
    204     }
    205     return true;
    206 }
    207 
    208 //层序遍历二叉树, 把所有的节点添加到队列中,包括空节点, 当遇到空节点的时候,查看其后是否
    209 //有非空节点, 有则不是完全二叉树
    210 bool isComplete1(node* root){
    211     if(root==NULL) return true;
    212     queue<node*> q;
    213     q.push(root);
    214     while(q.size()){
    215         node* temp=q.front();
    216         q.pop();
    217         if(temp){
    218             q.push(temp->left);
    219             q.push(temp->right);
    220         }else{
    221             while(q.size()){
    222                 if(q.front()) return false;
    223                 q.pop();
    224             }
    225         }
    226     }
    227     return true;
    228 }
    229 
    230 int DsonNode(node* root){
    231     if(root==NULL) return 0;
    232     if(root->left && root->right) return DsonNode(root->left) + DsonNode(root->right) + 1;
    233     return DsonNode(root->left) + DsonNode(root->right);
    234 }
    235 
    236 void reverse(node* &root){
    237     if(root==NULL) return;
    238     node* temp = root->left;
    239     root->left = root->right;
    240     root->right = temp;
    241     reverse(root->left);
    242     reverse(root->right);
    243 }
    244 
    245 //删除root以及其所有子节点
    246 void deleteNodes(node* root){
    247     if(root){
    248         deleteNodes(root->left);
    249         deleteNodes(root->right);
    250         delete(root);
    251     }
    252 }
    253 
    254 //删除所有值为x的节点
    255 void deleteX(node* root, int x){
    256     queue<node*> q;
    257     if(root->val==x){
    258         deleteNodes(root);
    259         return ;
    260     }
    261     q.push(root);
    262     while(q.size()){
    263         node* temp = q.front();
    264         q.pop();
    265         if(temp->left){
    266             if(temp->left->val==x){
    267                 deleteNodes(temp->left);
    268                 temp->left=NULL;
    269             }else q.push(temp->left);
    270         }
    271         if(temp->right){
    272             if(temp->right->val==x){
    273                 deleteNodes(temp->right);
    274                 temp->right=NULL;
    275             }else q.push(temp->right);
    276         }
    277     }
    278 }
    279 
    280 void rootsOfX(node* root, int x){
    281     stack<node*> s;
    282     node *p=root, *r;
    283     while(p || s.size()){
    284         if(p){
    285             if(p->val==x){
    286                 while(s.size()){
    287                     cout<<s.top()->val<<" ";
    288                     s.pop();
    289                 }
    290                 cout<<endl;
    291                 return;
    292             }
    293             s.push(p);
    294             p = p->left;
    295         }else{
    296             p = s.top();
    297             if(p->right && p->right!=r){
    298                 p=p->right;
    299                 s.push(p);
    300                 p=p->left;
    301             }else{
    302                 p = s.top();
    303                 s.pop();
    304                 r = p;
    305                 p = NULL;
    306             }
    307         }
    308     }
    309 }
    310 
    311 
    312  
    313 int main(){
    314     int a[]={7, 4, 10, 2, 5, 8, 11};
    315     int a1[]={7, 4, 10, 2, 5, 9, 8};
    316     char ch[]={'*','+','*','a','b','c','-','d'};
    317     node* root=NULL;
    318     for(int i=0; i<7; i++) insert(root, a[i]);
    319      
    320     level(root);
    321     rootsOfX(root, 4);
    322     level(root);
    323     preorder(root);
    324     inorder(root);
    325     reverselevel(root);
    326     post1(root);
    327   return 0;
    328 }
  • 相关阅读:
    网络编程
    网络参考模型
    面向对象中类的成员
    Forward(请求转发)和Redirect(重定向)的比较
    AOP详解
    JDK动态代理和CGLib代理对比
    内存可见性问题分析
    Java中创建对象的5种方式
    基于Spring的动态路由AbstractRoutingDataSource实现动态分库
    在java中String类为什么要设计成final?
  • 原文地址:https://www.cnblogs.com/mr-stn/p/9264929.html
Copyright © 2011-2022 走看看