二叉樹的線索化可以使得二叉樹的非遞迴遍歷不需借助棧或佇列這種資料結構,最主要的是可以為之提供迭代器。線索化二叉樹有三種方式:前序線索化、中序線索化、後序線索化(後序線索化需要三叉鏈結構)這裡主要講前序線索化和中序線索化,並為中序線索化提供迭代器。
線索化的思想就是將一顆二叉樹遍歷轉換成有序雙向鍊錶進行訪問。這樣二叉樹的節點結構就應該多乙個前驅和後繼的線索化標誌。
節點結構
};下面來看二叉樹線索化
template
t>
class
binarytreethd
node* creatertree
(t* a,size_t
n,const
t& invalid,size_t& index)
}void inorderthreading
()
void prevorderthreading
()
void prevorderthd
() //前序遍歷
cout<_data>
cur = cur->_right; //1,右子樹(子問題);2,線索化
}void inorderthd
() //中序遍歷
cout<_data>
//cur->_right 兩種情況:右子樹(子問題),線索化
while(cur->_righttypr == thread)
cur = cur->_right;
}cout
if(prev || prev->_right == null) //處理後繼
prev = root;
_inorderthreading(root->_right);
}_prevorderthreading(node* root,node* & prev) //前序線索化
if(prev && prev->_right == null)
prev = root;
_prevorderthreading(root->_left,prev);
_prevoederthreading(root->_right,prev);
}protected:
node* _node;
};
下面我們來為中序線索化提供迭代器。
template
class binarytreethditerator //迭代器
self& operator++() //對於中序,++肯定對應當前節點右子樹或右線索化
}return *this;
}self& operator++(int)
self& operator--() // --肯定是在當前節點左子樹或左線索化找
}
else
//左線索化,直接左跳
}self& operator--(int)
ref operator*()
ptr operator->()
bool
operator!=(const self& s) const
protected:
node* _node;
};template
class binarytreethd
return iterator(cur);
}iterator end() //取最右節點的迭代器
return iterator(cur);
}binarytreethd(t* a, size_t n, const t& invalid)
node* createtree(t* a, size_t n, const t& invalid, size_t& index)
return root;
}void inorderthd()
cout
<< cur->_data << " ";
while (cur->_righttype == thread)
cout
<< cur->_data << " ";
}cur = cur->_right;
}cout
<< endl;
}void prevorderthd() //線索化二叉樹前序遍歷
while (cur )
//訪問最左邊節點
cout
<< cur->_data << " ";
cur = cur->_right; //1,走右子樹; 2,調至下乙個節點}}
void inorderthreading()
void prevorderthreading()
protected:
void _prevorderthreading(node* root, node* & prev) //將上乙個節點的prev引用傳給現在節點,prev改變就能發現
if (prev && prev->_right == null)
prev = cur;
if (cur->_lefttype == link)
if (cur->_righttype == link)
}void _inorderthreading(node* root, node* & prev)
if (prev && prev->_right == null) //處理右繼 //保證上乙個節點不為空 && 右子樹為空
prev = cur;
_inorderthreading(cur->_right, prev); //後走右子樹
}private:
node* _root;
};
下面是驗證**
int main()
; binarytreethd t(a,sizeof(a)/sizeof(a[0],'#');
t1.inorderthreading();
binarytreethd::iterator it = t.begin();
if(it != t.end())
cout
<
}
二叉樹線索化
名稱 二叉樹線索化 說明 這個東西,一開始弄起來,我去,感覺老複雜了。照著書上看了好久,愣是沒看懂,照著敲了一遍,又手動模擬推了一遍,有了一點思路。照著把後序的線索化和遍歷也敲出來了。這裡要注意的是 對於中序來說,其能線索化後訪問到其前驅和後繼 可以理解為不通過棧訪問到 而對於後序來說,其只能不通過...
二叉樹線索化
public void infixthrnodes treenode node infixthrnodes node.lchild if node.lchild null if pre null pre.rchild null pre node infixthrnodes node.rchild 0...
二叉樹線索化
線索二叉樹 按照某種遍歷方式對二叉樹進行遍歷,可以把二叉樹中所有結點排序為乙個線性序列。在改序列中,除第乙個結點外每個結點有且僅有乙個直接前驅結點 除最後乙個結點外每乙個結點有且僅有乙個 直接後繼結點。這些指向直接前驅結點和指向直接後續結點的指標被稱為線索 thread 加了線索的二叉樹稱為線索二叉...