用set构建索引树~

使用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;
}
原文地址:https://www.cnblogs.com/whoiskevin/p/2628653.html