啓迪思惟:鏈式樹

最近公司項目比較忙,又加上要給十幾個新人作培訓,晚上和週末又要個姐姐裝修店鋪(太痛苦的事情,並且裝修的效果也不是很好),前些每天涯上有一篇寒門難出貴子帖子很火,那個做者語文水平和我一個級別的(錯別字太多了),你們能夠看淘寶鬼腳七整理版本(關注他的微信公衆號),雖然裏邊有些觀點不是很認同,但對我影響很大,出生寒門的兄弟必定去靜下心來好讀讀,這個遠比我下面寫的這邊技術文章帶給你更多思考,很是歡迎你們留言討論文章的觀點。html

前面的文章一直在分析數據結構中線性結構部分,從本篇文章之後將進入非線性結構部分,前面未弄懂部分能夠在網上找些視頻結合我寫的文章在補補,只有這樣後面學習起來才相對容易些,下面進入正題,首先仍是先分享一個軟件帶來誤會故事。
node

之前學校旁邊有一個火車票代售點,每次到過年學生放假的時候,偶爾會看有人由於先買沒有買到票,然後麪人確買到票和售票員吵架,估計每次發生這樣事情,售票員本身也解釋不清楚,連當時學計算機的我也猜想後面人給售票員好處,後來偶然看到一篇帖子才明白,原來火車票售票系統,會把必定數量的票鎖定給一個售票廳,前一我的買票時候,餘票被其餘售票廳鎖住了,後面去人再買票的時候正好遇上其餘售票廳釋放餘票(太幸運),如今技術和硬件愈來愈好,從09年後我就沒有見過爲這事吵架的。ios

 

一:概念面試

樹狀圖是一種數據結構,它是由nn>=1)個有限結點組成一個具備層次關係的集合。把它叫作「樹」是由於它看起來像一棵倒掛的樹,也就是說它是根朝上,而葉朝下的。它具備如下的特色:算法

1每一個結點有零個或多個子結點;數據庫

2沒有前驅的結點稱爲根結點;編程

3每個非根結點有且只有一個父結點;微信

4除了根結點外,每一個子結點能夠分爲m個不相交的子樹;數據結構

 

二:名稱解釋app

子孫:以某節點爲根的子樹中任一節點都稱爲該節點的子孫;

森林:由mm>=0)棵互不相交的樹的集合稱爲森林;

樹的度:一棵樹中,最大的節點的度稱爲樹的度;

節點的度:一個節點含有的子樹的個數稱爲該節點的度;

兄弟節點:具備相同父節點的節點互稱爲兄弟節點;

堂兄弟節點:雙親在同一層的節點互爲堂兄弟;

節點的祖先:從根到該節點所經分支上的全部節點;

節點的層次:從根開始定義起,根爲第1層,根的子節點爲第2層,以此類推;

樹的高度或深度:樹中節點的最大層次;

雙親節點或父節點:若一個結點含有子節點,則這個節點稱爲其子節點的父節點;

孩子節點或子節點:一個節點含有的子樹的根節點稱爲該節點的子節點;

葉節點或終端節點:度爲零的節點;

非終端節點或分支節點:度不爲零的節點;

 

三:示例圖

 

 

四:樹的應用

一、查找算法中應用(數據庫索引-B-tree)

二、哈夫曼編碼

三、最短路徑問題

四、幾乎全部的編譯器都須要實現一個表達式樹

上面這些樹的應用,面試中也會常常問到,爭取後面能寫比較好分析它們的文章

五:樹的分類

上面的截圖是維基百科裏邊的解釋,畫紅框的在後面的文章會分析到;

 

五:代碼分析

一、建立一顆樹

 1 /**
 2  *根據文件內容遞歸建立樹
 3  */
 4 void CreateTreeFromFile(ifstream &f) {
 5     //每次讀取一個字符
 6     T e;
 7     InputFromFile(f, e);
 8     if (e == '#') {
 9         return;
10     }
11 
12     //建立一個新的節點
13     root = new TNode<T> (e);
14 
15     //建立左右兩個樹對象
16     LinkTree<T> left, right;
17     //遞歸建立左子樹
18     left.CreateTreeFromFile(f);
19     //遞歸建立右子樹
20     right.CreateTreeFromFile(f);
21 
22     //設置根節點的左孩子接左子樹的根節點
23     root->lchild = left.root;
24     left.root = 0;
25     //設置根節點的右孩子接右子樹的根節點
26     root->rchild = right.root;
27     right.root = 0;
28 }
29 /**
30  *讀取文件並賦值給遍歷c
31  */
32 void InputFromFile(ifstream &f, T &c) {
33     f >> c;
34 }

二、清空一顆樹

 1 /**
 2  *清空樹的全部節點
 3  */
 4 void Clear() {
 5     Clear(root);
 6 }
 7 /**
 8  *根據節點遞歸清空樹
 9  */
10 void Clear(TNode<T>* t) {
11     //判斷指針是否爲空
12     if (t) {
13         //獲取資源當即放入管理對象(參考Effective C++裏邊條款13)
14         //tr1::shared_ptr(引用計數智慧指針)管理對象比auto_ptr更強大
15         std::auto_ptr<TNode<T> > new_ptr(t);
16 
17         //遞歸清空右子樹
18         Clear(new_ptr->rchild);
19 
20         //遞歸清空左子樹
21         Clear(new_ptr->lchild);
22     }
23 
24     //清空樹的根節點
25     t = 0;
26 }

三、判斷樹是否爲空

1 /**
2  * 若樹爲空,則返回true;不然返回false
3  */
4 bool IsEmpty() {
5     return root == 0;
6 }

四、計算樹的深度

 1 /**
 2  * 以傳入節點爲基礎計算樹的深度
 3  */
 4 int GetTreeDept(const TNode<T> *t) {
 5     int i, j;
 6     if (t == 0) {
 7         return 0;
 8     } else {
 9         //遞歸計算左子樹的深度
10         i = this->GetTreeDept(t->lchild);
11         //遞歸計算右子樹的深度
12         j = this->GetTreeDept(t->rchild);
13     }
14 
15     //t的深度爲其左右子樹中深度中的大者加1
16     return i > j ? i + 1 : j + 1;
17 }

五、前序非遞歸遍歷樹 

以下動畫flash不知道是網上那位大牛作,在這裏借用下,閱讀文章的朋友若是有作flash作的比較好,請幫忙指點下我,謝謝

以下中圖詳細分析下面代碼運行過程

 

以下代碼

 1 /**
 2  *前序非遞歸(利用棧)遍歷二叉樹
 3  *前序遍歷的規則:根左右
 4  *非遞歸遍歷樹會常常當作面試題,考察面試者的編程能力
 5  *防止下次被鄙視,應該深刻理解而且動手在紙寫出來
 6  */
 7 void PreOrderTraverse() {
 8     //申明一個棧對象
 9     stack<TNode<T>*> s;
10     //t首先指向根節點
11     TNode<T> *t = root;
12     //壓入一個空指針,做爲判斷條件
13     s.push(0);
14 
15     //若是t所值節點非空
16     while (t != 0) {
17         //直接訪問根節點
18         std::cout << (&t->data) << " ";
19 
20         //右孩子指針爲非空
21         if (t->rchild != 0) {
22             //入棧右孩子指針
23             s.push(t->rchild);
24         }
25 
26         //左孩子指針爲非空
27         if (t->lchild != 0) {
28             //直接指向其左孩子
29             t = t->lchild;
30         } else {//左孩子指針爲空
31             //獲取棧頂元素(右孩子指針)
32             t = s.top();
33             //清楚棧頂元素
34             s.pop();
35         }
36 
37     }
38 }

六、中序非遞歸遍歷樹

以下動畫flash不知道是網上那位大牛作,在這裏借用下,閱讀文章的朋友若是有作flash作的比較好,請幫忙指點下我,謝謝 

以下圖是代碼遍歷樹的節點順序,看的不是很明白的朋友,能夠像前面先序中那樣方式,用圖畫出每個步驟,便於跟好的理解

 

以下是代碼

 1 /**
 2  *中序非遞歸(利用棧)遍歷二叉樹
 3  *前序遍歷的規則:左根右
 4  */
 5 void InOrderTraverse() {
 6     //申明一個棧對象
 7     stack<TNode<T>*> s;
 8     //t首先指向根節點
 9     TNode<T>* t = root;
10 
11     //節點不爲空或者棧對象不爲空,都進入循環
12     while (t != 0 || !s.empty()) {
13         //若是t節點非空
14         if (t) {
15             //入棧t節點
16             s.push(t);
17             //t節點指向其左孩子
18             t = t->lchild;
19         } else {
20             //獲取棧頂元素(左孩子指針)
21             t = s.top();
22             //清楚棧頂元素
23             s.pop();
24             //直接訪問t節點
25             std::cout << (&t->data) << " ";
26             //t節點指向其右孩子
27             t = t->rchild;
28         }
29     }
30 }

七、後序非遞歸遍歷樹

以下動畫flash不知道是網上那位大牛作,在這裏借用下,閱讀文章的朋友若是有作flash作的比較好,請幫忙指點下我,謝謝  

以下圖是代碼遍歷樹的節點順序,看的不是很明白的朋友,能夠像前面先序中那樣方式,用圖畫出每個步驟,便於跟好的理解

以下是代碼

 1 /**
 2  *後序非遞歸(利用棧)遍歷二叉樹
 3  *前序遍歷的規則:左右根
 4  */
 5 void PostOrderTraverse() {
 6     //申明一個棧對象
 7     stack<TNode<T>*> s;
 8     //t首先指向根節點
 9     TNode<T>* t = root;
10     //申請中間變量,用作判斷標識
11     TNode<T>* r;
12     //節點不爲空或者棧對象不爲空,都進入循環
13     while (t != 0 || !s.empty()) {
14         //若是t節點非空
15         if (t) {
16             //入棧t節點
17             s.push(t);
18             //t節點指向其左孩子
19             t = t->lchild;
20         } else {
21             //獲取棧頂元素(左孩子指針)
22             t = s.top();
23             //判斷t的右子樹是否存在而且沒有訪問過
24             if (t->rchild && t->rchild != r) {
25                 //t節點指向其右孩子
26                 t = t->rchild;
27                 //入棧t節點
28                 s.push(t);
29                 //t節點指向其左孩子
30                 t = t->lchild;
31             } else {
32                 //獲取棧頂元素(左孩子指針)
33                 t = s.top();
34                 //清楚棧頂元素
35                 s.pop();
36                 //直接訪問t節點
37                 std::cout << (&t->data) << " ";
38                 //設置已經訪問過的節點,防止屢次訪問(右孩子指針)
39                 r = t;
40                 t = 0;
41             }
42         }
43     }
44 }

八、根據模式遞歸遍歷二叉樹

 1 /**
 2  * 根據模式遞歸遍歷二叉樹
 3  * 下面代碼相對比較簡單,只要記住遍歷樹的規則而且弄一點遞歸,均可以寫出來
 4  * 若是在面試中實在寫不出來非遞歸方式,能夠寫一個遞歸版本,也許能夠爭取一個好的工做
 5  */
 6 void OrderTraverse(const TNode<T>* t, Style mode) {
 7     if (t) {
 8         //先序遍歷二叉樹:根左右
 9         if (mode == Pre) {
10             //直接訪問t節點
11             std::cout << (&t->data) << " ";
12             //遞歸遍歷左子樹
13             this->OrderTraverse(t->lchild, mode);
14             //遞歸遍歷右子樹
15             this->OrderTraverse(t->rchild, mode);
16         }
17         //中序遍歷二叉樹:左根右
18         if (mode == In) {
19             //遞歸遍歷左子樹
20             this->OrderTraverse(t->lchild, mode);
21             //直接訪問t節點
22             std::cout << (&t->data) << " ";
23             //遞歸遍歷右子樹
24             this->OrderTraverse(t->rchild, mode);
25         }
26         //後序遍歷二叉樹:左右根
27         if (mode == Post) {
28             //遞歸遍歷左子樹
29             this->OrderTraverse(t->lchild, mode);
30             //遞歸遍歷右子樹
31             this->OrderTraverse(t->rchild, mode);
32             //直接訪問t節點
33             std::cout << (&t->data) << " ";
34         }
35     }
36 }

九、運行結果,因爲在虛擬機中打中文,實在太痛苦,弄一點英文裝下B

 測試代碼以下:

 1 void test() {
 2 
 3     ifstream fin("data.txt");
 4     this->CreateTreeFromFile(fin);
 5     std::cout << "create tree success" << std::endl;
 6 
 7     std::cout << "create tree after is null ? ";
 8     std::cout << boolalpha << this->IsEmpty();
 9 
10     std::cout << std::endl;
11     std::cout << "calculated depth of the tree begins" << std::endl;
12     std::cout << "tree is dept = " << this->GetTreeDept(this->GetRoot());
13     std::cout << std::endl;
14     std::cout << "calculated depth of the tree end" << std::endl;
15 
16     std::cout << std::endl;
17     std::cout << "not recursion--------------------begin" << std::endl;
18     std::cout << "pre order traverse: ";
19     this->PreOrderTraverse();
20     std::cout << std::endl;
21 
22     std::cout << "in order traverse: ";
23     this->InOrderTraverse();
24     std::cout << std::endl;
25 
26     std::cout << "post order traverse: ";
27     this->PostOrderTraverse();
28     std::cout << std::endl;
29     std::cout << "not recursion--------------------end" << std::endl;
30 
31     std::cout << std::endl;
32     std::cout << "recursion--------------------begin" << std::endl;
33     std::cout << "pre order traverse:";
34     this->OrderTraverse(this->GetRoot(), Pre);
35     std::cout << std::endl;
36 
37     std::cout << "in order traverse:";
38     this->OrderTraverse(this->GetRoot(), In);
39     std::cout << std::endl;
40 
41     std::cout << "post order traverse:";
42     this->OrderTraverse(this->GetRoot(), Post);
43     std::cout << std::endl;
44     std::cout << "recursion--------------------end" << std::endl;
45 }
View Code

十、完整代碼

TNode.h 

 1 /*
 2  * TLNode.h
 3  *
 4  *  Created on: 2013-7-6
 5  *      Author: sunysen
 6  */
 7 
 8 #ifndef TLNODE_H_
 9 #define TLNODE_H_
10 template <class T>
11 class TNode{
12 public:
13     T data;
14     TNode *rchild,*lchild;
15     TNode(T value):data(value),rchild(0),lchild(0){}
16 };
17 
18 #endif /* TLNODE_H_ */
View Code

  LinkTree.h

  1 /*
  2  * LinkTree.h
  3  *  Created on: 2013-7-6
  4  *      Author: sunysen
  5  */
  6 
  7 #ifndef LINKTREE_H_
  8 #define LINKTREE_H_
  9 #include "core/common/Common.h"
 10 #include "core/node/TNode.h"
 11 #include <queue>
 12 #include <stack>
 13 
 14 //樹的三種遍歷方式
 15 enum Style {
 16     Pre, In, Post
 17 };
 18 
 19 /**
 20  *鏈式樹
 21  */
 22 template<class T>
 23 class LinkTree {
 24 private:
 25     TNode<T> *root;//樹的根節點
 26 
 27     /**
 28      *讀取文件並賦值給遍歷c
 29      */
 30     void InputFromFile(ifstream &f, T &c) {
 31         f >> c;
 32     }
 33 
 34     /**
 35      *根據節點遞歸清空樹
 36      */
 37     void Clear(TNode<T>* t) {
 38         //判斷指針是否爲空
 39         if (t) {
 40             //獲取資源當即放入管理對象(參考Effective C++裏邊條款13)
 41             //tr1::shared_ptr(引用計數智慧指針)管理對象比auto_ptr更強大
 42             std::auto_ptr<TNode<T> > new_ptr(t);
 43 
 44             //遞歸清空右子樹
 45             Clear(new_ptr->rchild);
 46 
 47             //遞歸清空左子樹
 48             Clear(new_ptr->lchild);
 49         }
 50 
 51         //清空樹的根節點
 52         t = 0;
 53     }
 54 public:
 55     /**
 56      * 構造函數初始化樹根節點
 57      */
 58     LinkTree() :
 59         root(0) {
 60     }
 61     /**
 62      *析構行數釋放全部構造的資源
 63      */
 64     ~LinkTree() {
 65         Clear();
 66     }
 67 
 68     /**
 69      *根據文件內容遞歸建立樹
 70      */
 71     void CreateTreeFromFile(ifstream &f) {
 72         //每次讀取一個字符
 73         T e;
 74         InputFromFile(f, e);
 75         if (e == '#') {
 76             return;
 77         }
 78 
 79         //建立一個新的節點
 80         root = new TNode<T> (e);
 81 
 82         //建立左右兩個樹對象
 83         LinkTree<T> left, right;
 84         //遞歸建立左子樹
 85         left.CreateTreeFromFile(f);
 86         //遞歸建立右子樹
 87         right.CreateTreeFromFile(f);
 88 
 89         //設置根節點的左孩子接左子樹的根節點
 90         root->lchild = left.root;
 91         left.root = 0;
 92         //設置根節點的右孩子接右子樹的根節點
 93         root->rchild = right.root;
 94         right.root = 0;
 95     }
 96 
 97     /**
 98      * 若樹爲空,則返回true;不然返回false
 99      */
100     bool IsEmpty() {
101         return root == 0;
102     }
103     /**
104      *清空樹的全部節點
105      */
106     void Clear() {
107         Clear(root);
108     }
109 
110     /**
111      *獲取const修飾的根節點,至關於作一次類型轉換
112      */
113     const TNode<T>* GetRoot() {
114         return root;
115     }
116 
117     /**
118      * 以傳入節點爲基礎計算樹的深度
119      */
120     int GetTreeDept(const TNode<T> *t) {
121         int i, j;
122         if (t == 0) {
123             return 0;
124         } else {
125             //遞歸計算左子樹的深度
126             i = this->GetTreeDept(t->lchild);
127             //遞歸計算右子樹的深度
128             j = this->GetTreeDept(t->rchild);
129         }
130 
131         //t的深度爲其左右子樹中深度中的大者加1
132         return i > j ? i + 1 : j + 1;
133     }
134 
135 
136     /**
137      *前序非遞歸(利用棧)遍歷二叉樹
138      *前序遍歷的規則:根左右
139      *非遞歸遍歷樹會常常當作面試題,考察面試者的編程能力
140      *防止下次被鄙視,應該深刻理解而且動手在紙寫出來
141      */
142     void PreOrderTraverse() {
143         //申明一個棧對象
144         stack<TNode<T>*> s;
145         //t首先指向根節點
146         TNode<T> *t = root;
147         //壓入一個空指針,做爲判斷條件
148         s.push(0);
149 
150         //若是t所值節點非空
151         while (t != 0) {
152             //直接訪問根節點
153             std::cout << (&t->data) << " ";
154 
155             //右孩子指針爲非空
156             if (t->rchild != 0) {
157                 //入棧右孩子指針
158                 s.push(t->rchild);
159             }
160 
161             //左孩子指針爲非空
162             if (t->lchild != 0) {
163                 //直接指向其左孩子
164                 t = t->lchild;
165             } else {//左孩子指針爲空
166                 //獲取棧頂元素(右孩子指針)
167                 t = s.top();
168                 //清楚棧頂元素
169                 s.pop();
170             }
171 
172         }
173     }
174 
175     /**
176      *中序非遞歸(利用棧)遍歷二叉樹
177      *前序遍歷的規則:左根右
178      */
179     void InOrderTraverse() {
180         //申明一個棧對象
181         stack<TNode<T>*> s;
182         //t首先指向根節點
183         TNode<T>* t = root;
184 
185         //節點不爲空或者棧對象不爲空,都進入循環
186         while (t != 0 || !s.empty()) {
187             //若是t節點非空
188             if (t) {
189                 //入棧t節點
190                 s.push(t);
191                 //t節點指向其左孩子
192                 t = t->lchild;
193             } else {
194                 //獲取棧頂元素(左孩子指針)
195                 t = s.top();
196                 //清楚棧頂元素
197                 s.pop();
198                 //直接訪問t節點
199                 std::cout << (&t->data) << " ";
200                 //t節點指向其右孩子
201                 t = t->rchild;
202             }
203         }
204     }
205     /**
206      *後序非遞歸(利用棧)遍歷二叉樹
207      *前序遍歷的規則:左右根
208      */
209     void PostOrderTraverse() {
210         //申明一個棧對象
211         stack<TNode<T>*> s;
212         //t首先指向根節點
213         TNode<T>* t = root;
214         //申請中間變量,用作判斷標識
215         TNode<T>* r;
216         //節點不爲空或者棧對象不爲空,都進入循環
217         while (t != 0 || !s.empty()) {
218             //若是t節點非空
219             if (t) {
220                 //入棧t節點
221                 s.push(t);
222                 //t節點指向其左孩子
223                 t = t->lchild;
224             } else {
225                 //獲取棧頂元素(左孩子指針)
226                 t = s.top();
227                 //判斷t的右子樹是否存在而且沒有訪問過
228                 if (t->rchild && t->rchild != r) {
229                     //t節點指向其右孩子
230                     t = t->rchild;
231                     //入棧t節點
232                     s.push(t);
233                     //t節點指向其左孩子
234                     t = t->lchild;
235                 } else {
236                     //獲取棧頂元素(左孩子指針)
237                     t = s.top();
238                     //清楚棧頂元素
239                     s.pop();
240                     //直接訪問t節點
241                     std::cout << (&t->data) << " ";
242                     //設置已經訪問過的節點,防止屢次訪問(右孩子指針)
243                     r = t;
244                     t = 0;
245                 }
246             }
247         }
248     }
249     /**
250      * 根據模式遞歸遍歷二叉樹
251      * 下面代碼相對比較簡單,只要記住遍歷樹的規則而且弄一點遞歸,均可以寫出來
252      * 若是在面試中實在寫不出來非遞歸方式,能夠寫一個遞歸版本,也許能夠爭取一個好的工做
253      */
254     void OrderTraverse(const TNode<T>* t, Style mode) {
255         if (t) {
256             //先序遍歷二叉樹:根左右
257             if (mode == Pre) {
258                 //直接訪問t節點
259                 std::cout << (&t->data) << " ";
260                 //遞歸遍歷左子樹
261                 this->OrderTraverse(t->lchild, mode);
262                 //遞歸遍歷右子樹
263                 this->OrderTraverse(t->rchild, mode);
264             }
265             //中序遍歷二叉樹:左根右
266             if (mode == In) {
267                 //遞歸遍歷左子樹
268                 this->OrderTraverse(t->lchild, mode);
269                 //直接訪問t節點
270                 std::cout << (&t->data) << " ";
271                 //遞歸遍歷右子樹
272                 this->OrderTraverse(t->rchild, mode);
273             }
274             //後序遍歷二叉樹:左右根
275             if (mode == Post) {
276                 //遞歸遍歷左子樹
277                 this->OrderTraverse(t->lchild, mode);
278                 //遞歸遍歷右子樹
279                 this->OrderTraverse(t->rchild, mode);
280                 //直接訪問t節點
281                 std::cout << (&t->data) << " ";
282             }
283         }
284     }
285 
286     void test() {
287 
288         ifstream fin("data.txt");
289         this->CreateTreeFromFile(fin);
290         std::cout << "create tree success" << std::endl;
291 
292         std::cout << "create tree after is null ? ";
293         std::cout << boolalpha << this->IsEmpty();
294 
295         std::cout << std::endl;
296         std::cout << "calculated depth of the tree begins" << std::endl;
297         std::cout << "tree is dept = " << this->GetTreeDept(this->GetRoot());
298         std::cout << std::endl;
299         std::cout << "calculated depth of the tree end" << std::endl;
300 
301         std::cout << std::endl;
302         std::cout << "not recursion--------------------begin" << std::endl;
303         std::cout << "pre order traverse: ";
304         this->PreOrderTraverse();
305         std::cout << std::endl;
306 
307         std::cout << "in order traverse: ";
308         this->InOrderTraverse();
309         std::cout << std::endl;
310 
311         std::cout << "post order traverse: ";
312         this->PostOrderTraverse();
313         std::cout << std::endl;
314         std::cout << "not recursion--------------------end" << std::endl;
315 
316         std::cout << std::endl;
317         std::cout << "recursion--------------------begin" << std::endl;
318         std::cout << "pre order traverse:";
319         this->OrderTraverse(this->GetRoot(), Pre);
320         std::cout << std::endl;
321 
322         std::cout << "in order traverse:";
323         this->OrderTraverse(this->GetRoot(), In);
324         std::cout << std::endl;
325 
326         std::cout << "post order traverse:";
327         this->OrderTraverse(this->GetRoot(), Post);
328         std::cout << std::endl;
329         std::cout << "recursion--------------------end" << std::endl;
330     }
331 
332 };
333 
334 #endif /* LINKTREE_H_ */
View Code

Common.h 

 1 /*
 2  * Common.h
 3  *
 4  *  Created on: May 17, 2012
 5  *      Author: sunysen
 6  */
 7 
 8 #ifndef COMMON_H_
 9 #define COMMON_H_
10 
11 #include <iostream>
12 #include <fstream>
13 #include "memory"
14 #include "string"
15 #include "string.h"
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <math.h>
19 
20 
21 using namespace std;
22 #endif /* COMMON_H_ */
View Code

六:環境

1、運行環境:Ubuntu 10.04 LTS+VMware8.0.4+gcc4.4.3

2、開發工具:Eclipse+make

七:題記

1、上面的代碼不免有bug,若是你發現代碼寫的有問題,請你幫忙指出,讓咱們一塊兒進步,讓代碼變的更漂亮和更健壯;

2、我本身能手動寫上面代碼,離不開郝斌、高一凡、侯捷、嚴蔚敏等老師的書籍和視頻指導,在這裏感謝他們;

3、鼓勵本身能堅持把更多數據結構方面的知識寫出來,讓本身掌握更深入,也順便冒充下"小牛"

 

 

歡迎繼續閱讀「啓迪思惟:數據結構和算法」系列

相關文章
相關標籤/搜索