http://www.cppblog.com/zoyi-hang/archive/2008/04/06/46355.html
trie 樹
好不容易寫的一個模版~本來是想按照我們數據結構教程的trie樹來寫,但是他的實現我實在覺得太難
所以還是采用簡化版的trie樹
這個應該算是比較標準的trie樹結構,但是他的插入實現起來不僅僅是插入本身的單詞,可能還需要修改原來的數結構
比如說本身已經存在了bobwhite,現在添加bobwhq,就要在第二層的基礎上繼續擴展,bobwhite的位置也要重新定位,刪除操作也是這樣
可能還要上移某些單詞,這個昨天試了很久,寫出來的都不行。
而且對這種字典樹的結構本身我的理解就很混亂。
簡化版的trie樹
以下這種實現方法是根據別人改編的,昨天被逼得沒辦法還是覺得簡化版的,突然發現個牛人的寫法和我的很相似(這著實還讓我激動了下下),就邊學習邊改了,呵呵
它是根據杭電的一道題來寫的,以下是我的代碼:
http://acm.hdu.edu.cn/showproblem.php?pid=1247
#include
<
iostream
>
#define
keyNum26
#define
MaxN50
struct
trie
{
struct
trieNode
{
//
trie結點的結構
trieNode
*
link[keyNum];
//
下標為'A','B','C',,'Z'的指針數組
int
num[keyNum];
//
插入key的次數
trieNode()
{
memset(num,
0
,
sizeof
(num));
memset(link,NULL,
sizeof
(link));
}
void
init()
{
memset(link,NULL,
sizeof
(link));
memset(num,
0
,
sizeof
(num));
}
}
;
trieNode
*
root;
trie()
{
root
=
(trieNode
*
)malloc(
sizeof
(trieNode));
//
初始化時為root申請了空間
root
->
init();
}
bool
Search(
char
*
);
void
Insert(
char
[]);
void
Delete(trieNode
*
);
}
;
bool
trie::Search(
char
*
x)
{
if
(
*
x
==
0
)
return
false
;
trieNode
*
current
=
root;
x
++
;
while
(
*
x)
{
if
(current
->
link[
*
(x
-
1
)
-
'
a
'
])
current
=
current
->
link[
*
(x
-
1
)
-
'
a
'
];
else
break
;
x
++
;
}
if
(
*
x
==
0
&&
current
->
num[
*
(x
-
1
)
-
'
a
'
])
return
true
;
else
return
false
;
}
void
trie::Delete(trieNode
*
t)
{
int
i;
for
(i
=
0
;i
<
keyNum;i
++
)
if
(t
->
link[i])Delete(t
->
link[i]);
memset(t
->
num,
0
,
sizeof
(t
->
num));
delete(t);
}
void
trie::Insert(
char
x[])
{
trieNode
*
current
=
root;
int
i
=
1
;
while
(x[i])
{
if
(current
->
link[x[i
-
1
]
-
'
a
'
]
==
NULL)
{
current
->
link[x[i
-
1
]
-
'
a
'
]
=
(trieNode
*
)malloc(
sizeof
(trieNode));
(current
->
link[x[i
-
1
]
-
'
a
'
])
->
init();
}
current
=
current
->
link[x[i
-
1
]
-
'
a
'
];
i
++
;
}
(current
->
num[x[i
-
1
]
-
'
a
'
])
++
;
}
char
c[
50000
][MaxN],tmp;
int
main()
{
triea;
int
i
=
0
,j,num;
while
(scanf(
"
%s
"
,c[i])
!=
EOF)
a.Insert(c[i
++
]);
num
=
i;
for
(i
=
0
;i
<
num;i
++
)
for
(j
=
1
;c[i][j];j
++
)
{
tmp
=
c[i][j];
c[i][j]
=
0
;
if
(a.Search(c[i]))
{
c[i][j]
=
tmp;
if
(a.Search(
&
c[i][j]))
{
printf(
"
%s
"
,c[i]);
break
;}
}
else
c[i][j]
=
tmp;
}
a.Delete(a.root);
return
0
;
}
所以還是采用簡化版的trie樹
這個應該算是比較標準的trie樹結構,但是他的插入實現起來不僅僅是插入本身的單詞,可能還需要修改原來的數結構
比如說本身已經存在了bobwhite,現在添加bobwhq,就要在第二層的基礎上繼續擴展,bobwhite的位置也要重新定位,刪除操作也是這樣
可能還要上移某些單詞,這個昨天試了很久,寫出來的都不行。
而且對這種字典樹的結構本身我的理解就很混亂。
簡化版的trie樹
以下這種實現方法是根據別人改編的,昨天被逼得沒辦法還是覺得簡化版的,突然發現個牛人的寫法和我的很相似(這著實還讓我激動了下下),就邊學習邊改了,呵呵
它是根據杭電的一道題來寫的,以下是我的代碼:
http://acm.hdu.edu.cn/showproblem.php?pid=1247






















































































還有遍歷節點,都不是很方便的。
以上代碼解釋幾點:
首先我構造了一格trie的結構:在此結構中有root,和這棵樹的基本三個操作
再次trie結構中的每個節點都是trieNode的結構,包括root也是
這棵樹是動態生成的,所以對trieNode的init很重要,這點寫過的就知道,不Init會出現很多問題的,
在trieNode結構中主要有26個link和26個num,剛開始我自己寫的時候就是這26個num搞不清,只寫了一個num,這是對樹結構的理解混亂造成的
num在這里是標記這個單詞插入的次數,為0表示這個單詞還沒有被插入過
trieNode還有個很重要的成員函數就是init了。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
