青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

liyuxia713

蹣跚前行者

常用鏈接

統計

Algorithms

C++

最新評論

二叉樹抽象類型

這個二叉樹的功能算很全面了~~
由給定的完全二叉樹形式存儲的數組(如"12345 6"),構造二叉樹
提供:復制構造函數和賦值操作符重載,遞歸和非遞歸形式的中、前、后序遍歷方法,求一個節點的父節點,左右兄弟結點的函數以及 求二叉樹深度和結點個數的函數。

 1// BTreeNode.h
 2// 二叉樹結點抽象類型
 3
 4#ifndef BTREENODE_H
 5#define BTREENODE_H
 6
 7#include <cstdlib>
 8
 9template<class T> class BTree;
10template<class T> class BTreeNode
11{
12    friend class BTree<T>;
13public:
14    BTreeNode():lchild(NULL),rchild(NULL){    };
15    BTreeNode(const T&dt, BTreeNode<T> *lch =NULL , BTreeNode<T> *rch = NULL)
16        :data(dt),lchild(lch),rchild(rch){};
17
18    T get_data()const {return data;    };    
19    BTreeNode<T>* get_lchild()const {return lchild;    };
20    BTreeNode<T>* get_rchild()const {return rchild;    };
21    
22private:
23    T data;
24    BTreeNode<T> *lchild, *rchild;
25}
;
26#endif

  

  1/************************************************************************
  2** BTree.h二叉樹抽象類型
  3** 由給定的完全二叉樹形式存儲的數組(如"12345 6"),構造二叉樹
  4** 提供:復制構造函數和賦值操作符重載   
  5** 遞歸和非遞歸形式的中、前、后序遍歷方法
  6** 求一個節點的父節點,左右兄弟結點的函數     
  7** 求二叉樹深度和結點個數的函數                                                       
  8************************************************************************/

  9#ifndef BTREE_H
 10#define BTREE_H
 11
 12#include "BTreeNode.h"
 13#include <stack> //非遞歸遍歷時借用棧
 14#include <cstdlib> //NULL的定義在這里
 15
 16template <class T>
 17class BTree
 18{
 19private:
 20    BTreeNode<T>* build_body(T*elems, int n, int i); //構造二叉樹時使用    
 21    BTreeNode<T>* root;
 22public:
 23    //三個構造函數
 24    BTree(T *a,int m);
 25    BTree(BTreeNode<T> *= NULL) { root = new BTreeNode<T>; copy_body(root, p);    };
 26    BTree(const T& t, BTree<T>& ltree, BTree<T>& rtree)
 27    {
 28        root = new BTreeNode<T>(t, ltree.root, rtree.root);    
 29        //原來兩顆子樹的根結點設置為空,避免非法訪問,否則遍歷時會出錯,創建新樹之前可以復制原來兩棵樹
 30        ltree.root = rtree.root = NULL;
 31    }
;
 32    //復制構造函數
 33    BTree(BTree& bt){root = new BTreeNode<T>; copy_body(root,bt.root);};        
 34    ~BTree() { destry(root); }
 35
 36    //重載復制操作符
 37    BTree<T>& operator = (const BTree<T>& nbt) {root = new BTreeNode<T>; copy_body(root,nbt.root);};
 38    //遞歸復制二叉樹    
 39    static void copy_body(BTreeNode<T>*&p, BTreeNode<T>* q);            
 40    //遞歸遍歷
 41    static void in_order(BTreeNode<T>*p, void visit(BTreeNode<T>* p));    
 42    static void pre_order(BTreeNode<T>*p, void visit(BTreeNode<T>* p));    
 43    static void post_order(BTreeNode<T>*p, void visit(BTreeNode<T>* p));
 44    virtual void pre_order(void visit(BTreeNode<T>* p))const {pre_order(root, visit);};
 45    virtual void in_order(void visit(BTreeNode<T>* p))const {in_order(root, visit);    };
 46    virtual void post_order(void visit(BTreeNode<T>* p))const {post_order(root, visit);    };
 47    //非遞歸遍歷
 48    virtual void in_order1(void visit(BTreeNode<T>* p))const;
 49    virtual void pre_order1(void visit(BTreeNode<T>* p))const;
 50    virtual void post_order1(void visit(BTreeNode<T>* p))const;
 51
 52    BTreeNode<T>* get_root()const{return root;}//返回二叉樹根
 53    BTreeNode<T>* get_parent(BTreeNode<T> *curr)const//返回給定結點父節點
 54    //定義見get_parent函數,只需修改一條語句
 55    BTreeNode<T>* get_left_sibling(BTreeNode<T>* curr)const//返回給定結點左兄弟結點
 56    //定義見get_parent函數,只需修改一條語句
 57    BTreeNode<T>* get_right_sibling(BTreeNode<T>* curr)const//返回給定結點右兄弟結點
 58    void set_root(BTreeNode<T>* p) { destry(root); copy_body(root, p);};
 59    
 60    //釋放內存資源
 61    static void destry(BTreeNode<T> *&p);
 62
 63    //求二叉樹結點個數
 64    static int num(BTreeNode<T>* p);
 65    int num()const return num(root);};
 66    //求二叉樹深度
 67    static int depth(BTreeNode<T>* p);
 68    int depth()const {return depth(root);};
 69    //判斷二叉樹是否相等
 70    static bool equal(BTreeNode<T> *p, BTreeNode<T> *q);
 71    bool operator ==(BTree<T>&bt) const {return equal(root, bt.root);};
 72}
;
 73
 74//構造函數
 75template<class T>
 76BTree<T>::BTree(T *a,int m)
 77{        
 78    root = build_body(a, m, 1);//自作聰明,從0開始調用函數,導致l=2*i=0,沒有輸出結果,莫名其妙了半天
 79}
;
 80
 81//構造子樹
 82template <class T>
 83BTreeNode<T>* BTree<T>::build_body(T*elems, int n, int i)//suffix
 84{
 85    BTreeNode<T> *p;
 86    int l,r;
 87    if( i <= n && elems[i-1!= ' ')
 88    {
 89         p = new BTreeNode<T>;
 90         p->data = elems[i-1];
 91         l = 2*i; //左兒子結點位置
 92         r = 2*+ 1//右兒子結點位置
 93         p->lchild = build_body(elems,n,l);
 94         p->rchild = build_body(elems,n,r);
 95         return p;
 96    }

 97    else
 98        return NULL;
 99}

100
101//復制二叉樹
102template<class T>
103void BTree<T>::copy_body(BTreeNode<T>* &p, BTreeNode<T> *q)
104{
105    if(q != NULL)
106    {
107        if(p == NULL)
108            p = new BTreeNode<T>;
109        p->data = q->data;
110        copy_body(p->lchild,q->lchild);
111        copy_body(p->rchild,q->rchild);
112    }

113    else  p = NULL;
114}

115
116//遞歸中序遍歷
117template<class T>
118void BTree<T>::in_order(BTreeNode<T>*p, void visit(BTreeNode<T>* p))
119{
120    if(p != NULL)
121    {
122        in_order(p->lchild,visit);
123        visit(p);
124        in_order(p->rchild,visit);
125    }

126}

127//遞歸前序遍歷
128template<class T>
129void BTree<T>::pre_order(BTreeNode<T>*p,void visit(BTreeNode<T>*p))
130{
131    if(p != NULL)
132    {
133        visit(p);
134        pre_order(p->lchild,visit);
135        pre_order(p->rchild,visit);
136    }

137}

138//遞歸后序遍歷
139template<class T>
140void BTree<T>::post_order(BTreeNode<T>*p,void visit(BTreeNode<T>*p))
141{
142    if(p != NULL)
143    {
144        post_order(p->lchild,visit);
145        post_order(p->rchild,visit);
146        visit(p);
147    }

148}

149//非遞歸中序遍歷
150template<class T>
151void BTree<T>::in_order1( void visit(BTreeNode<T>* p))const
152{
153    cout << "The inorder is : ";
154    std::stack< BTreeNode<T>* > stk;
155    BTreeNode<T> * q; 
156    stk.push(root); //根結點進棧
157
158    while!stk.empty()) //若棧非空,重復
159    {
160        while(stk.top() != NULL) //棧頂結點的左兒子相繼進棧,直到NULL為止
161        {
162            q= stk.top()->lchild;
163            stk.push(q);                
164        }

165        stk.pop(); //將NULL退出棧
166
167        if!stk.empty()) //訪問棧頂結點,并將其跳出棧
168        {
169            q = stk.top();
170            stk.pop();
171            visit(q);
172            stk.push(q->rchild); //將原棧頂結點的右子樹壓入棧
173        }

174    }

175    cout << endl;
176}

177
178//非遞歸前序遍歷
179template<class T>
180void BTree<T>::pre_order1(void visit(BTreeNode<T>*p))const
181{
182    cout << "The preorder is: " ;
183    std::stack< BTreeNode<T>* > stk;
184    BTreeNode<T>* q;
185    
186    visit(root); 
187    stk.push(root); //訪問根節點,并將其壓入棧
188    while!stk.empty())
189    {
190        while(stk.top() != NULL) //相繼訪問棧頂結點的左兒子,并將其壓入棧,直至NULL
191        {
192            q = stk.top()->lchild;
193            if(q != NULL) visit(q);
194            stk.push(q);
195        }

196        
197        stk.pop(); // 將NULL跳出棧
198
199        if!stk.empty())
200        {
201            q = stk.top()->rchild; //標記原棧頂結點右兒子結點
202            stk.pop(); // 棧頂結點跳出棧
203            if( q != NULL)    visit(q); 
204            stk.push(q); //訪問右兒子結點并將其壓入棧
205        }

206    }

207    cout << endl;
208}

209
210//非遞歸后序遍歷
211template <class T>
212void BTree<T>::post_order1(void visit(BTreeNode<T>* p))const
213{
214    cout << "The postorder is: ";
215    std::stack< BTreeNode<T>* > stk;
216    BTreeNode<T> *= NULL, *pre = NULL; //pre記錄前一個訪問的節點
217    
218    stk.push(root);
219
220    while!stk.empty()) //最后是樹根是如何跳出循環
221    {
222        while(stk.top() != NULL) //棧頂結點的左兒子結點相繼進棧,直到NULL
223            stk.push(stk.top()->lchild);
224        
225        stk.pop(); //NULL跳出棧
226
227        if(!stk.empty())
228        {
229            q = stk.top(); //棧頂結點跳出
230            stk.pop();    
231            // 當棧頂結點有右兒子,且沒有被訪問過時,將原棧頂結點重新壓入棧,并將其右兒子也壓入棧
232            if(q->rchild != NULL && !equal(q->rchild,pre))
233            {
234                stk.push(q);
235                stk.push(q->rchild);
236            }

237            // 不然,訪問原棧頂結點,為防止重復遍歷右兒子,將NULL壓入棧
238            else
239            {
240                visit(q);
241                stk.push(NULL); 
242                pre = q;
243            }

244        }
        
245    }

246    cout << endl;
247}

248
249//求雙親結點
250//實質就是在中序遍歷的時候順便判斷一下給定結點是不是某一節點的兒子結點
251template<class T>
252BTreeNode<T>* BTree<T>::get_parent(BTreeNode<T> *curr)const
253{
254    
255    cout << "The parent of " << curr->get_data() << " is: "
256    std::stack< BTreeNode<T>* > stk;
257    BTreeNode<T> *p, *q;
258    p = NULL;
259    stk.push(root);
260
261    while!stk.empty())
262    {
263        while(stk.top() != NULL)
264        {
265            q= stk.top()->lchild;
266            stk.push(q);                
267        }

268        stk.pop();
269
270        if!stk.empty())
271        {
272            q = stk.top();
273            stk.pop();
274            //求雙親結點
275            if(q->lchild == curr || q->rchild == curr) p = q;
276            //求左兄弟結點
277            //if(q->rchild == curr) p = q->lchild;
278            //求右兄弟結點
279            //if(q->lchild == curr) p = q->rchild;
280            stk.push(q->rchild);
281        }

282    }

283    return p;
284}

285
286//釋放資源
287template<class T>
288void BTree<T>::destry(BTreeNode<T> *&p)
289{
290    if(p != NULL)
291    {
292        destry(p->lchild);
293        destry(p->rchild);
294        delete p;
295    }

296    p = NULL;
297}

298
299//求二叉樹結點個數
300template<class T>
301int BTree<T>::num(BTreeNode<T>* p)
302{
303    if(p == NULL) return 0;
304    else return num(p->lchild) + num(p->rchild) + 1;
305}

306
307//求二叉樹深度
308template<class T>
309int BTree<T>::depth(BTreeNode<T>* p)
310{
311    int max = 0;
312    if(p == NULL) return 0;
313    else
314    {
315        max = depth(p->lchild);
316        if(depth(p->rchild) > max) max = depth(p->rchild);
317        return (max + 1);
318    }

319}

320
321//判斷二叉樹是否相等
322template<class T>
323bool BTree<T>::equal(BTreeNode<T> *p, BTreeNode<T> *q)
324{
325    bool b = true;
326    if((p == NULL) && (q == NULL)) ;
327    else if((p == NULL) || (q == NULL)) b = false;
328    else
329    {
330        b = (p->data == q->data) && (p->lchild == q->lchild) && (p->rchild == q->rchild);
331    }

332    return b;
333}

334    
335#endif
 1//MainFn.cpp 測試二叉樹功能
 2
 3#include "BTree.h"
 4#include <iostream>
 5
 6using std::endl;
 7using std::cout;
 8
 9//謂詞函數predicate,定義訪問二叉樹結點的形式
10void visit(BTreeNode<char> *p) { cout << p->get_data() << " ";};
11
12int main()
13{
14    char *str = "12345 6";//字符數組的定義形式
15    char *str2 = "78 9";
16    BTree<char> bt(str,7);
17    BTree<char> bt_copy(bt);
18    BTree<char> bt_copy2(bt.get_root());
19    BTree<char> bt_copy3 = bt;
20    BTree<char> bt2(str2,4);
21
22    //BTree<char> bt3('a',bt,bt2); //創建新樹,注意創建完這個樹以后原先的兩個樹bt,bt2已經無效,不能再調用
23    //bt3.in_order1(visit);
24
25    //測試構造函數
26    bt.in_order1(visit);
27    bt_copy.in_order1(visit);
28    bt_copy2.in_order1(visit);
29    bt_copy3.in_order1(visit);
30    //測試遍歷函數
31    bt.pre_order1(visit);
32    cout << "Postorder is :";
33    bt.post_order(visit);
34    cout <<endl;
35    bt.post_order1(visit);
36    //測試求二叉樹結點個數和深度的函數及其他
37    cout << bt.num() << "," << bt.depth() <<endl;
38    cout << bt.get_parent(bt.get_root()->get_lchild())->get_data() <<endl; //求雙親結點
39    
40    return 0;
41}

posted on 2009-04-28 08:40 幸運草 閱讀(1280) 評論(0)  編輯 收藏 引用 所屬分類: Data Structure


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲欧美999| 99综合在线| 国产精品每日更新在线播放网址| 久久久久网址| 欧美一级成年大片在线观看| 99精品久久久| 亚洲日本va在线观看| 久久久久在线观看| 性久久久久久久久久久久| 一本色道久久| 亚洲精品国产拍免费91在线| 精品白丝av| 国产一区二区成人| 国产日韩欧美成人| 国产精品日韩欧美| 国产精品久99| 欧美午夜理伦三级在线观看| 欧美精品v国产精品v日韩精品| 久久一区二区三区四区| 久久精品国产综合精品| 欧美在线亚洲在线| 午夜在线视频观看日韩17c| 亚洲一区二区毛片| 亚洲视频一区在线| 在线综合视频| 这里只有精品视频在线| 亚洲视频1区| 亚洲亚洲精品三区日韩精品在线视频| 一区二区三区久久精品| 9l国产精品久久久久麻豆| 亚洲精品亚洲人成人网| 99视频在线观看一区三区| 99精品福利视频| 一个色综合av| 亚洲一区999| 亚洲欧美中文日韩v在线观看| 亚洲欧美日产图| 先锋资源久久| 久久―日本道色综合久久| 久久亚洲精品一区二区| 欧美成人一区在线| 欧美日韩成人网| 国产精品久久久久久久久久久久久久 | 久久综合九色综合网站| 久久人人看视频| 免费在线欧美视频| 欧美日本免费一区二区三区| 欧美四级在线| 国产女人18毛片水18精品| 国产一区二区中文| 亚洲国产日韩欧美一区二区三区| 亚洲黄网站在线观看| 99国产精品视频免费观看| 亚洲影院在线| 久久视频国产精品免费视频在线| 美女网站在线免费欧美精品| 亚洲国产精品久久久久久女王| 亚洲精品乱码久久久久久蜜桃麻豆| 一区二区精品| 久久国产精品久久久| 欧美国产日本高清在线| 欧美色大人视频| 国产主播一区二区三区| 亚洲精品视频免费| 午夜亚洲视频| 欧美高清不卡| 一区二区欧美日韩视频| 欧美专区在线观看| 欧美精品三级在线观看| 国产日本精品| 日韩视频在线一区二区三区| 亚洲欧美一级二级三级| 欧美成人亚洲成人| 亚洲视频999| 免费亚洲电影| 国产伦精品一区二区三区视频孕妇| 在线观看不卡| 亚洲欧美日韩一区二区在线| 蜜桃久久av| 亚洲午夜精品久久久久久app| 久久久亚洲欧洲日产国码αv| 欧美三级特黄| 亚洲国产日日夜夜| 欧美亚洲综合在线| 亚洲人成精品久久久久| 欧美一区二区在线看| 欧美日韩免费观看一区=区三区| 国产在线播精品第三| 一区二区三区不卡视频在线观看 | 99精品欧美一区二区三区| 欧美在线精品一区| 亚洲精品在线看| 久久网站免费| 国产一二精品视频| 亚洲综合丁香| 亚洲日产国产精品| 美女日韩在线中文字幕| 国产视频一区二区三区在线观看| 亚洲美女黄色| 欧美成人一区二区三区在线观看 | 在线欧美不卡| 久久福利资源站| 一本久道久久综合婷婷鲸鱼| 模特精品在线| 又紧又大又爽精品一区二区| 欧美怡红院视频| 在线综合视频| 欧美日韩国产麻豆| 亚洲日本aⅴ片在线观看香蕉| 久久亚洲国产精品一区二区 | 99国产一区| 欧美激情综合在线| 亚洲三级电影全部在线观看高清| 久久久久国产精品一区二区| 亚洲欧美国产精品专区久久| 欧美午夜精品理论片a级按摩 | 亚洲国产91| 玖玖玖国产精品| 性欧美办公室18xxxxhd| 国产乱码精品| 欧美一区2区三区4区公司二百| 一本色道久久综合亚洲精品小说| 欧美韩日视频| 日韩视频一区二区三区在线播放| 亚洲第一页自拍| 蜜月aⅴ免费一区二区三区 | 国精产品99永久一区一区| 欧美一级午夜免费电影| 亚洲欧美久久| 国产欧美在线观看一区| 久久xxxx精品视频| 性视频1819p久久| 国产一区二区日韩| 久久亚洲捆绑美女| 久久久噜噜噜久噜久久| 亚洲国产精品一区二区三区| 欧美国产亚洲视频| 欧美极品在线观看| 亚洲视频成人| 亚洲免费视频观看| 国精产品99永久一区一区| 久久一区中文字幕| 牛牛国产精品| 亚洲色图制服丝袜| 亚洲在线成人| 狠狠色丁香久久婷婷综合丁香| 美日韩精品免费| 欧美精品激情| 亚洲欧美成aⅴ人在线观看| 午夜国产精品影院在线观看 | 中文日韩在线| 亚洲一区二区视频| 好看的亚洲午夜视频在线| 欧美高清一区二区| 欧美日韩国产综合新一区| 亚洲一区二区三区影院| 午夜精品影院在线观看| 亚洲国产精品久久久久婷婷884| 亚洲人体影院| 国产精品一区二区你懂得| 蜜臀久久99精品久久久久久9| 欧美大片在线观看一区| 亚洲一区免费看| 欧美一区二区三区免费大片| 亚洲欧洲在线一区| 亚洲视频在线观看一区| 黄色一区三区| 亚洲理论电影网| 国产欧美一区二区色老头| 欧美激情一二区| 国产精品午夜在线观看| 欧美激情成人在线| 国产精品毛片大码女人| 欧美电影免费| 国产精品一区免费在线观看| 欧美不卡在线| 国产精品入口66mio| 欧美激情91| 国产日产欧产精品推荐色 | 亚洲美女在线视频| 亚洲欧美日韩国产精品 | 欧美激情一二区| 久久成人在线| 欧美日韩一区视频| 老鸭窝91久久精品色噜噜导演| 欧美日韩妖精视频| 蜜桃av久久久亚洲精品| 国产精品美女久久久久久免费 | 亚洲一级片在线观看| 在线观看日韩av先锋影音电影院| 这里只有精品视频在线| 91久久久精品| 久久精品中文字幕一区二区三区| 一区二区日本视频| 久久久久综合一区二区三区| 亚洲欧美在线一区| 欧美日韩另类国产亚洲欧美一级| 美女爽到呻吟久久久久| 国产欧美一区二区精品性| 亚洲另类自拍|