程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 二元樹中和為某一值的所有路徑(我看到網上很多答案是錯的)

二元樹中和為某一值的所有路徑(我看到網上很多答案是錯的)

編輯:C++入門知識

題目:輸入一個整數和一棵二元樹。從樹的根結點開始往下訪問一直到葉結點所經過的所有結點形成一條路徑。打印出和與輸入整數相等的所有路徑。


例如輸入整數22和如下二元樹

                                            10
                                           /   \
                                          5     12
                                        /   \  
                                      4     7

則打印出兩條路徑:10, 12和10, 5, 7。

 

我的思路,貌似有點復雜了,用一個vector和stack存儲數據,vector輸出路徑,stack用來保存路徑,因為用stack輸出就要全部出棧,數據會丟失。

網上的答案,包括某些大神寫的,都是有部分問題的,度為1的節點輸入就出bug了。突然想到想糾正bug,於是寫了如下程序。

 

 

[cpp]
#include <iostream>  
#include <vector>  
#include <stack>  
using namespace std; 
//節點  
struct node 

    node *lchild,*rchild; 
    int value; 
}; 
 
//二元查找樹  
class list 

public: 
    list(); 
    //這裡的m_print函數用做遞歸,print函數相當於外面的一個套子  
    void print(int num); 
private: 
    //將遞歸函數私有化  
    void m_print(node *p,int value,int num,bool flag); 
private: 
    node* root; 
    vector<int> v; 
    stack<node*> s; 
}; 
void list::m_print(node *p,int value,int num,bool flag) 

    if(p==NULL) 
        return; 
    value+=p->value; 
    v.push_back(p->value); 
    s.push(p); 
    //到葉子節點返回  
    if(NULL==p->lchild && NULL==p->rchild){ 
          if(value==num){ 
              for(vector<int>::iterator iter=v.begin();iter!=v.end();iter++) 
                       cout<<*iter<<"   "; 
              cout<<endl; 
          } 
          v.pop_back(); 
          s.pop(); 
          if(flag==1){ 
              v.pop_back(); 
              s.pop(); 
          } 
          while(1){ 
              if(!s.empty() && !s.top()->rchild){ 
                     s.pop(); 
                     v.pop_back(); 
              } 
              else 
                  break; 
          } 
          return; 
    } 
    //向左右方向遞歸  
    m_print(p->lchild,value,num,0); 
    m_print(p->rchild,value,num,1); 
 

 
 
void list::print(int num) 

    v.clear(); 
    m_print(root,0,num,0); 

 
list::list() 

    cout<<"請輸入您要輸入的節點,按'#'退出:"<<endl; 
    int i; 
    //用cin.fail(),cin.bad()判斷也行  
    if(cin>>i==NULL){ 
      cout<<"您的輸入有誤"<<endl; 
      exit(-1); 
    } 
    //創建根節點  
    root=new node; 
    root->value=i; 
    root->lchild=NULL; 
    root->rchild=NULL; 
    //建立兩個臨時節點,p開辟新節點,q為二元查找定位  
    node *p,*q; 
    while(cin>>i!=NULL){ 
        //開辟新節點  
        p=new node; 
        p->value=i; 
        p->lchild=NULL; 
        p->rchild=NULL; 
        //二元查找樹比較從q=root開始,小則轉左,大則轉右,如果有位置就插入  
        q=root; 
        while(1){ 
            //插入節點小於該節點比較值,左節點為空則插入,否則q=q->lchild繼續判斷  
            if(p->value<q->value){ 
                if(q->lchild) 
                    q=q->lchild; 
                else{ 
                    q->lchild=p; 
                    break; 
                } 
            } 
            //插入節點大於該節點比較值,右節點為空則插入,否則q=q->rchild繼續判斷  
            else if(p->value>q->value){ 
                if(q->rchild) 
                    q=q->rchild; 
                else{ 
                    q->rchild=p; 
                    break; 
                } 
            } 
            //如果兩節點相等,直接退出程序(有些暴力)  
            else{ 
                cout<<"node repeated!!"<<endl; 
                exit(-1); 
            } 
        } 
    } 

 
void main() 

    list test; 
    //這裡的print函數打印出所有的根節點到所有葉子節點的長度  
    test.print(22);  
    system("pause"); 

#include <iostream>
#include <vector>
#include <stack>
using namespace std;
//節點
struct node
{
 node *lchild,*rchild;
 int value;
};

//二元查找樹
class list
{
public:
 list();
 //這裡的m_print函數用做遞歸,print函數相當於外面的一個套子
 void print(int num);
private:
 //將遞歸函數私有化
 void m_print(node *p,int value,int num,bool flag);
private:
 node* root;
 vector<int> v;
 stack<node*> s;
};
void list::m_print(node *p,int value,int num,bool flag)
{
 if(p==NULL)
  return;
 value+=p->value;
 v.push_back(p->value);
 s.push(p);
 //到葉子節點返回
 if(NULL==p->lchild && NULL==p->rchild){
          if(value==num){
     for(vector<int>::iterator iter=v.begin();iter!=v.end();iter++)
                 cout<<*iter<<"   ";
     cout<<endl;
    }
    v.pop_back();
    s.pop();
    if(flag==1){
     v.pop_back();
     s.pop();
    }
    while(1){
     if(!s.empty() && !s.top()->rchild){
         s.pop();
         v.pop_back();
     }
     else
      break;
    }
    return;
 }
 //向左右方向遞歸
 m_print(p->lchild,value,num,0);
 m_print(p->rchild,value,num,1);

}


void list::print(int num)
{
 v.clear();
 m_print(root,0,num,0);
}

list::list()
{
 cout<<"請輸入您要輸入的節點,按'#'退出:"<<endl;
 int i;
 //用cin.fail(),cin.bad()判斷也行
 if(cin>>i==NULL){
      cout<<"您的輸入有誤"<<endl;
   exit(-1);
 }
 //創建根節點
 root=new node;
 root->value=i;
 root->lchild=NULL;
 root->rchild=NULL;
 //建立兩個臨時節點,p開辟新節點,q為二元查找定位
 node *p,*q;
 while(cin>>i!=NULL){
  //開辟新節點
  p=new node;
  p->value=i;
  p->lchild=NULL;
  p->rchild=NULL;
  //二元查找樹比較從q=root開始,小則轉左,大則轉右,如果有位置就插入
  q=root;
  while(1){
   //插入節點小於該節點比較值,左節點為空則插入,否則q=q->lchild繼續判斷
   if(p->value<q->value){
    if(q->lchild)
     q=q->lchild;
    else{
     q->lchild=p;
     break;
    }
   }
   //插入節點大於該節點比較值,右節點為空則插入,否則q=q->rchild繼續判斷
   else if(p->value>q->value){
    if(q->rchild)
     q=q->rchild;
    else{
     q->rchild=p;
     break;
    }
   }
   //如果兩節點相等,直接退出程序(有些暴力)
   else{
    cout<<"node repeated!!"<<endl;
    exit(-1);
   }
  }
 }
}

void main()
{
 list test;
 //這裡的print函數打印出所有的根節點到所有葉子節點的長度
 test.print(22); 
 system("pause");
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved