使用set来构建一个索引树。用来查找指定文件名。
暂时不知道有没有BUG,还在测,不过内存泄露应该不会有吧,IndexTree_release(), IndexTree_Destory() 应该能保证所有节点被释放。
使用过程中的临时节点也被释放了。
看代码:
IndexTree.h:
1 #ifndef IndexTree_h__ 2 #define IndexTree_h__ 3 4 #include <tchar.h> 5 #include <set> 6 using namespace std; 7 8 class IndexTreeNode; 9 struct IndexTreeNodeCompare 10 { 11 bool operator()(IndexTreeNode* first, IndexTreeNode* sencond) const; 12 }; 13 14 class IndexTreeNode 15 { 16 public: 17 TCHAR m_value; 18 std::set<IndexTreeNode*, IndexTreeNodeCompare> m_next; 19 bool m_isEnd; 20 21 public: 22 IndexTreeNode(); 23 IndexTreeNode(TCHAR value):m_value(value){}; 24 ~IndexTreeNode(); 25 int compare(IndexTreeNode* second); 26 }; 27 28 class IndexTree 29 { 30 private: 31 IndexTreeNode* m_root; 32 33 protected: 34 IndexTreeNode* CreateNode(TCHAR value); 35 void DestoryNode(IndexTreeNode* node); 36 void DestoryTree(); 37 38 public: 39 IndexTree(); 40 ~IndexTree(); 41 int IndexTree_init(TCHAR DataList[][260], int nItemNum); 42 int IndexTree_add(TCHAR* Data); 43 void IndexTree_release(); 44 IndexTreeNode* IndexTree_find(TCHAR* FoundData); 45 }; 46 47 #endif // IndexTree_h__
IndexTree.cpp:
#include "stdafx.h" #include "IndexTree.h" #include <iostream> #include <queue> using namespace std; bool IndexTreeNodeCompare::operator()(IndexTreeNode* first, IndexTreeNode* sencond) const { if(first == sencond) return true; return first->compare(sencond); } IndexTreeNode::IndexTreeNode() { m_value = ' '; m_isEnd = false; m_next.clear(); } IndexTreeNode::~IndexTreeNode() { m_value = ' '; m_isEnd = false; m_next.clear(); } int IndexTreeNode::compare(IndexTreeNode* second) { return this->m_value > second->m_value; } IndexTree::IndexTree() { m_root = CreateNode(' '); } IndexTree::~IndexTree() { DestoryTree(); } int IndexTree::IndexTree_init(TCHAR DataList[][260], int nItemNum) { if(m_root == NULL) { m_root = CreateNode(' '); } for(int i = 0; i < nItemNum; i++) { if(!IndexTree_add(DataList[i])) return false; } return true; } int IndexTree::IndexTree_add(TCHAR* Data) { int nLen = _tcslen(Data); IndexTreeNode* cur = m_root; set<IndexTreeNode*, IndexTreeNodeCompare>::iterator iter; pair<set<IndexTreeNode*, IndexTreeNodeCompare>::iterator, bool> ret; for(int i=0; i<nLen; i++) { IndexTreeNode* node = CreateNode(Data[i]); iter = cur->m_next.find(node); if(iter == cur->m_next.end()) //找不到就insert { ret = cur->m_next.insert(node); if(ret.second == true) { cur = *ret.first; if(i == nLen-1) cur->m_isEnd = true; } else return false; } else //找到了就修改cur为此节点 { cur = *iter; DestoryNode(node); //记得释放临时节点 } } return true; } IndexTreeNode* IndexTree::CreateNode(TCHAR value) { IndexTreeNode* node = new IndexTreeNode; node->m_value = value; node->m_next.clear(); node->m_isEnd = false; return node; } void IndexTree::DestoryNode(IndexTreeNode* node) { delete node; } IndexTreeNode* IndexTree::IndexTree_find(TCHAR* FoundData) { int nLen = _tcslen(FoundData); IndexTreeNode* cur = m_root; set<IndexTreeNode*, IndexTreeNodeCompare>::iterator iter; for(int i = 0; i < nLen; i++) { IndexTreeNode* node = CreateNode(FoundData[i]); iter = cur->m_next.find(node); DestoryNode(node); if(iter == cur->m_next.end()) { return NULL; } else { cur = *iter; } } if(cur->m_isEnd == true) return cur; else return NULL; } void IndexTree::DestoryTree() { IndexTree_release(); delete m_root; } void IndexTree::IndexTree_release() { queue<IndexTreeNode*> q; set<IndexTreeNode*, IndexTreeNodeCompare>::iterator iter; q.push(m_root); while(!q.empty()) { IndexTreeNode* temp = q.front(); if(!temp->m_next.empty()) { for(iter = temp->m_next.begin(); iter != temp->m_next.end(); iter++) { q.push(*iter); } } q.pop(); if(temp != m_root) delete(temp); } m_root->m_next.clear(); }
使用测试:
// TestIndexTree.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "IndexTree.h" int _tmain(int argc, _TCHAR* argv[]) { TCHAR FileNameList[100][260] = {L"root", L"home", L"etc", L"bin",L"roob"}; IndexTree* FileNameTree = new IndexTree; FileNameTree->IndexTree_init(FileNameList, 5); IndexTreeNode* x = FileNameTree->IndexTree_find(L"bi"); FileNameTree->IndexTree_release(); delete FileNameTree; return 0; }