以前在完成TinySTL項目中二叉搜索樹的設計時發現要想完成其中序迭代器的設計,關鍵的一步是完成迭代器的++操做,當實現了這個操做時那麼這個迭代器的90%的操做均可以很快的完成了。node
下面先來看看node的定義:git
struct node{ typedef T value_type; T data_; node *left_; node *right_; explicit node(T d = T(), node *l = 0, node *r = 0) :data_(d), left_(l), right_(r){} };
在二叉樹中有:github
下面來看看我是怎樣實現++操做的。this
首先是初始化迭代器:spa
1 template<class T> 2 bst_iter<T>::bst_iter(const T *ptr, cntrPtr container) 3 :ptr_(ptr), container_(container){ 4 if (!ptr_) 5 return; 6 auto temp = container_->root_; 7 while (temp && temp != ptr_ && temp->data_ != ptr_->data_){ 8 parent_.push(temp); 9 if (temp->data_ < ptr_->data_){ 10 //temp向右走說明temo指向的父節點不須要再次訪問了 11 visited_.insert(temp);//add 2015.01.14 12 temp = temp->right_; 13 } 14 else if (temp->data_ > ptr_->data_){ 15 temp = temp->left_; 16 } 17 } 18 }
在初始化的過程當中傳入任意的樹中節點指針ptr,而後從root開始沿着向下的方向用一個棧parent_來依次記錄節點的父節點,同時我用一個set visited_來記錄父節點相對於這個節點來講是不是已經訪問過的狀態,當節點處於這個父節點的右子樹中時這個節點被記錄。根據中序遍歷的定義來看,當要訪問任意節點的下一個節點的時候,若是節點還有右子樹未訪問則跳轉到右子樹的最小節點,當節點沒有右子樹的時候咱們須要沿着父節點的順序後退,此時不是全部的父節點都須要訪問的,只有當節點處於父節點的左子樹時,此時這個父節點才須要訪問。設計
1 template<class T> 2 bst_iter<T>& bst_iter<T>::operator ++(){ 3 visited_.insert(ptr_);//此node被訪問 4 if (ptr_->right_){//此node還有右子樹 5 //rvisited_.insert(ptr_); 6 parent_.push(ptr_); 7 ptr_ = ptr_->right_; 8 while (ptr_ && ptr_->left_){ 9 parent_.push(ptr_); 10 ptr_ = ptr_->left_; 11 } 12 }else{//node無右子樹則只能向父節點路徑移動 13 ptr_ = 0;//add 2015.01.14 14 while (!parent_.empty()){ 15 ptr_ = parent_.top(); 16 parent_.pop(); 17 if (visited_.count(ptr_) == 0){//父節點還沒有訪問,此時ptr_指向此節點 18 visited_.insert(ptr_); 19 break; 20 } 21 ptr_ = 0;//設爲哨兵 22 }//end of while 23 }//end of if 24 return *this; 25 }
第4-11行代碼處理節點有右子樹的狀況。第12-23行代碼處理節點無右子樹須要向父節點移動的狀況。指針