VB哈希表的实现

前端之家收集整理的这篇文章主要介绍了VB哈希表的实现前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
  1. VERSION 5.00
  2. Begin VB.Form Form1
  3. Caption = "Form1"
  4. ClientHeight = 1935
  5. ClientLeft = 60
  6. ClientTop = 345
  7. ClientWidth = 3600
  8. LinkTopic = "Form1"
  9. ScaleHeight = 1935
  10. ScaleWidth = 3600
  11. StartUpPosition = 3 '窗口缺省
  12. Begin VB.CommandButton Command3
  13. Caption = "与COLLECTION对象运行效率比较"
  14. Height = 495
  15. Left = 960
  16. TabIndex = 2
  17. Top = 1320
  18. Width = 1575
  19. End
  20. Begin VB.CommandButton Command2
  21. Caption = "哈希表遍历测试"
  22. Height = 495
  23. Left = 960
  24. TabIndex = 1
  25. Top = 720
  26. Width = 1575
  27. End
  28. Begin VB.CommandButton Command1
  29. Caption = "哈希表"
  30. Height = 495
  31. Left = 960
  32. TabIndex = 0
  33. Top = 120
  34. Width = 1575
  35. End
  36. End
  37. Attribute VB_Name = "Form1"
  38. Attribute VB_GlobalNameSpace = False
  39. Attribute VB_Creatable = False
  40. Attribute VB_PredeclaredId = True
  41. Attribute VB_Exposed = False
  42. Private Sub Command1_Click()
  43. '
  44. Dim cHash As clsHashLK
  45. Dim i As Long
  46. Set cHash = New clsHashLK
  47. cHash.AlloMem 7000
  48. For i = 1 To 2500
  49. cHash.Add i,i * 10 + i
  50. Next i
  51. For i = 1 To 2500
  52. cHash.Add i,-(i * 10 + i)
  53. Next i
  54. Debug.Print cHash.Item(11)
  55. Debug.Print cHash.Item(-27500)
  56. Debug.Print cHash.Item(5500)
  57. Debug.Print cHash.IsKeyExist(1),cHash.IsKeyExist(2200)
  58. Set cHash = Nothing
  59. End Sub
  60.  
  61. Private Sub Command2_Click()
  62. '
  63. Dim cHash As clsHashLK
  64. Dim i As Long
  65. Dim datOne As Long,keyOne As Long,blEndTrav As Boolean
  66. Dim strOne As String,lngOne As Long
  67. Set cHash = New clsHashLK
  68. For i = 1 To 15
  69. cHash.Add i,i * 2
  70. Next i
  71. blEndTrav = False
  72. cHash.startTraversal
  73. datOne = cHash.NextItem(lngOne,strOne,keyOne,blEndTrav)
  74. i = 0
  75. Do Until blEndTrav
  76. Debug.Print keyOne; "->"; datOne,i = i + 1: If i Mod 5 = 0 Then Debug.Print ""
  77. datOne = cHash.NextItem(lngOne,blEndTrav)
  78. Loop
  79. Debug.Print ""
  80. Set cHash = Nothing
  81. End Sub
  82.  
  83. Private Sub Command3_Click()
  84. '
  85. Command3.Enabled = False
  86. Dim cHash As clsHashLK
  87. Dim col As Collection
  88. Dim datOne As Long,blEndTrav As Boolean
  89. Dim sngTimer As Single
  90. Dim i As Long
  91. sngTimer = Timer
  92. Set cHash = New clsHashLK
  93. cHash.AlloMem 70000
  94. For i = 1 To 50000
  95. cHash.Add i,i * 10 + i
  96. Next i
  97. Debug.Print "哈希表插入数据结束,耗时:"; Timer - sngTimer; "秒"
  98. sngTimer = Timer
  99. Set col = New Collection
  100. For i = 1 To 50000
  101. col.Add i,CStr(i * 10 + i)
  102. Next i
  103. Debug.Print "COLLECTION插入数据结束,耗时:"; Timer - sngTimer; "秒"
  104. sngTimer = Timer
  105. For i = 1 To 50000
  106. datOne = cHash.Item(i * 10 + i)
  107. Next i
  108. Debug.Print "哈希表按键访问数据结束,耗时:"; Timer - sngTimer; "秒"
  109. sngTimer = Timer
  110. With col
  111. For i = 1 To 50000
  112. datOne = .Item(CStr(i * 10 + i))
  113. Next i
  114. End With
  115. Debug.Print "COLLECTION按键访问数据结束,耗时:"; Timer - sngTimer; "秒"
  116. sngTimer = Timer
  117. cHash.startTraversal
  118. datOne = cHash.NextData(blEndTrav)
  119. i = 1
  120. Do Until blEndTrav
  121. datOne = cHash.NextData(blEndTrav)
  122. i = i + 1
  123. Loop
  124. Debug.Print "哈希表遍历数据结束,耗时:"; Timer - sngTimer; "秒",i
  125. sngTimer = Timer
  126. With col
  127. For i = 1 To 50000
  128. datOne = .Item(i)
  129. Next i
  130. End With
  131. Debug.Print "COLLECTION遍历数据结束,耗时:"; Timer - sngTimer; "秒",i
  132. Set col = Nothing
  133. Set cHash = Nothing
  134. Command3.Enabled = True
  135. End Sub






  1. VERSION 1.0 CLASS
  2. BEGIN
  3. MultiUse = -1 'True
  4. Persistable = 0 'NotPersistable
  5. DataBindingBehavior = 0 'vbNone
  6. DataSourceBehavior = 0 'vbNone
  7. MTSTransactionMode = 0 'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "clsHashLK"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. Option Explicit
  15.  
  16. Private Type Hs_DataType
  17. Key As Long
  18. Data As Long
  19. DataLong As Long
  20. DataString As String
  21. Used As Byte
  22. End Type
  23.  
  24. Private lMem() As Hs_DataType,lMemCount As Long,lMemUsedCount As Long
  25. Private lMem2() As Hs_DataType,lMemCount2 As Long,lMemUsedCount2 As Long
  26. Private mTravIdxCurr As Long
  27.  
  28. Private Const mcIniMemSize As Long = 10
  29. Private Const mcMaxItemCount As Long = 214748364
  30. Private Const mcExpandMaxPort As Single = 0.75
  31. Private Const mcExpandCountThres As Long = 10000
  32. Private Const mcExpandCountThresMax As Long = 10000000
  33. Private Const mcExpandBigPer As Long = 1000000
  34. Private Const mcExpandMem2Per As Long = 10
  35. Private Const mcSeqMax As Long = 5
  36.  
  37. Public Function Add(ByVal Data As Long,ByVal Key As Long,Optional ByVal DataLong As Long,Optional ByVal DataString As String,_
  38. Optional ByVal RaiseErrorIfNotHas As Boolean = True) As Boolean
  39. '
  40. Dim lngIdx As Long
  41. If lMemUsedCount + lMemUsedCount2 > mcMaxItemCount Then
  42. If RaiseErrorIfNotHas Then Err.Raise 7
  43. Add = False
  44. Exit Function
  45. End If
  46. If IsKeyExist(Key) Then
  47. If RaiseErrorIfNotHas Then Err.Raise 5
  48. Add = False
  49. Exit Function
  50. End If
  51. lngIdx = AlloMemIndex(Key)
  52. If lngIdx > 0 Then
  53. With lMem(lngIdx)
  54. .Data = Data
  55. .DataLong = DataLong
  56. .DataString = DataString
  57. .Key = Key
  58. .Used = 1
  59. End With
  60. lMemUsedCount = lMemUsedCount + 1
  61. Else
  62. With lMem2(-lngIdx)
  63. .Data = Data
  64. .DataLong = DataLong
  65. .DataString = DataString
  66. .Key = Key
  67. .Used = 1
  68. End With
  69. lMemUsedCount2 = lMemUsedCount2 + 1
  70. End If
  71. mTravIdxCurr = 0
  72. Add = True
  73. End Function
  74.  
  75. Public Function Item(ByVal Key As Long,Optional ByVal RaiseErrorIfNotHas As Boolean = True) As Long
  76. '
  77. Dim lngIdx As Long
  78. lngIdx = FindMemIndex(Key)
  79. If lngIdx = 0 Then
  80. If RaiseErrorIfNotHas Then Err.Raise 5
  81. Item = 0
  82. Exit Function
  83. ElseIf lngIdx > 0 Then
  84. Item = lMem(lngIdx).Data
  85. Else
  86. Item = lMem2(-lngIdx).Data
  87. End If
  88. End Function
  89.  
  90. Public Function DataLong(ByVal Key As Long,Optional ByVal RaiseErrorIfNotHas As Boolean = True) As Long
  91. '
  92. Dim lngIdx As Long
  93. lngIdx = FindMemIndex(Key)
  94. If lngIdx = 0 Then
  95. If RaiseErrorIfNotHas Then Err.Raise 5
  96. DataLong = 0
  97. Exit Function
  98. ElseIf lngIdx > 0 Then
  99. DataLong = lMem(lngIdx).DataLong
  100. Else
  101. DataLong = lMem2(-lngIdx).DataLong
  102. End If
  103. End Function
  104.  
  105. Public Function DataString(ByVal Key As Long,Optional ByVal RaiseErrorIfNotHas As Boolean = True) As String
  106. '
  107. Dim lngIdx As Long
  108. lngIdx = FindMemIndex(Key)
  109. If lngIdx = 0 Then
  110. If RaiseErrorIfNotHas Then Err.Raise 5
  111. DataString = ""
  112. Exit Function
  113. ElseIf lngIdx > 0 Then
  114. DataString = lMem(lngIdx).DataString
  115. Else
  116. DataString = lMem2(-lngIdx).DataString
  117. End If
  118. End Function
  119.  
  120. Public Function Remove(ByVal Key As Long,Optional ByVal RaiseErrorIfNotHas As Boolean = True) As Boolean
  121. '
  122. Dim lngIdx As Long
  123. lngIdx = FindMemIndex(Key)
  124. If lngIdx = 0 Then
  125. If RaiseErrorIfNotHas Then Err.Raise 5
  126. Remove = False
  127. Exit Function
  128. ElseIf lngIdx > 0 Then
  129. With lMem(lngIdx)
  130. .Used = 0
  131. .Key = 0
  132. End With
  133. lMemUsedCount = lMemUsedCount - 1
  134. Else
  135. Dim i As Long
  136. For i = -lngIdx To lMemUsedCount2 - 1
  137. lMem2(i) = lMem(i + 1)
  138. Next i
  139. lMemUsedCount2 = lMemUsedCount2 - 1
  140. End If
  141. mTravIdxCurr = 0
  142. Remove = True
  143. End Function
  144.  
  145. Private Function AlloMemIndex(ByVal Key As Long,Optional ByVal CanExpandMem As Boolean = True) As Long
  146. '
  147. Const cMaxNumForSquare As Long = 46340
  148. Dim idxMod As Long,idxSq As Long
  149. Dim idxModRev As Long,idxSqRev As Long
  150. Dim lngCount As Long
  151. Dim keyToCalc As Long
  152. keyToCalc = Key
  153. If keyToCalc < 0 Then keyToCalc = 0 - keyToCalc
  154. lngCount = lMemUsedCount + lMemUsedCount2
  155. ' 1
  156. idxMod = keyToCalc Mod lMemCount + 1
  157. If lMem(idxMod).Used = 0 Then AlloMemIndex = idxMod: Exit Function
  158. ' 2
  159. If keyToCalc <= cMaxNumForSquare Then
  160. idxSq = (keyToCalc * keyToCalc) Mod lMemCount + 1
  161. Else
  162. idxSq = Sqr(keyToCalc) Mod lMemCount + 1
  163. End If
  164. If lMem(idxSq).Used = 0 Then AlloMemIndex = idxSq: Exit Function
  165. ' 3
  166. idxModRev = lMemCount - idxMod + 1
  167. If lMem(idxModRev).Used = 0 Then AlloMemIndex = idxModRev: Exit Function
  168. ' 4
  169. idxSqRev = lMemCount - idxSq + 1
  170. If lMem(idxSqRev).Used = 0 Then AlloMemIndex = idxSqRev: Exit Function
  171. ' 5
  172. If CanExpandMem And lngCount > mcExpandMaxPort * lMemCount Then
  173. ExpandMem
  174. AlloMemIndex = AlloMemIndex(Key,CanExpandMem)
  175. Exit Function
  176. End If
  177. Dim lngRetIdx As Long
  178. Dim idxMdSta As Long,idxMdEnd As Long
  179. idxMdSta = idxMod - mcSeqMax
  180. idxMdEnd = idxMod + mcSeqMax
  181. lngRetIdx = AlloSeqIdx(idxMdSta,idxMod - 1)
  182. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  183. lngRetIdx = AlloSeqIdx(idxMod + 1,idxMdEnd)
  184. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  185. Dim lngSqSta As Long,lngSqEnd As Long
  186. lngSqSta = idxSq - mcSeqMax: lngSqEnd = idxSq + mcSeqMax
  187. If lngSqSta < 1 Then lngSqSta = 1
  188. If lngSqEnd > lMemCount Then lngSqEnd = lMemCount
  189. If lngSqEnd < idxMdSta Then
  190. lngRetIdx = AlloSeqIdx(lngSqSta,lngSqEnd)
  191. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  192. ElseIf lngSqEnd <= idxMdEnd Then
  193. If lngSqSta < idxMdSta Then
  194. lngSqEnd = idxMdSta - 1
  195. lngRetIdx = AlloSeqIdx(lngSqSta,lngSqEnd)
  196. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  197. Else
  198. lngSqSta = 0: lngSqEnd = 0
  199. End If
  200. Else
  201. If lngSqSta > idxMdEnd Then
  202. lngRetIdx = AlloSeqIdx(lngSqSta,lngSqEnd)
  203. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  204. ElseIf lngSqSta >= idxMdSta Then
  205. lngSqSta = idxMdEnd + 1
  206. lngRetIdx = AlloSeqIdx(lngSqSta,lngSqEnd)
  207. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  208. Else
  209. lngRetIdx = AlloSeqIdx(lngSqSta,idxMdSta - 1)
  210. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  211. lngRetIdx = AlloSeqIdx(idxMdEnd + 1,lngSqEnd)
  212. If lngRetIdx > 0 Then AlloMemIndex = lngRetIdx: Exit Function
  213. End If
  214. End If
  215. If lMemUsedCount2 + 1 > lMemCount2 Then
  216. lMemCount2 = lMemCount2 + mcExpandMem2Per
  217. ReDim Preserve lMem2(1 To lMemCount2)
  218. End If
  219. AlloMemIndex = -(lMemUsedCount2 + 1)
  220. End Function
  221.  
  222. Private Function AlloSeqIdx(ByVal fromIndex As Long,ByVal toIndex As Long) As Long
  223. '
  224. Dim i As Long,fCt As Long
  225. If fromIndex <= 0 Then fromIndex = 1
  226. If toIndex > lMemCount Then toIndex = lMemCount
  227. For i = fromIndex To toIndex
  228. If lMem(i).Used = 0 Then AlloSeqIdx = i: Exit Function
  229. Next i
  230. AlloSeqIdx = 0
  231. End Function
  232.  
  233. Private Sub ExpandMem()
  234. '
  235. Dim lngCount As Long,lngPreMemCount As Long
  236. lngCount = lMemUsedCount + lMemUsedCount2
  237. If lngCount < lMemCount Then lngCount = lMemCount
  238. lngPreMemCount = lMemCount
  239. If lngCount < mcExpandCountThres Then
  240. lngCount = lngCount * 2
  241. ElseIf lngCount < mcExpandCountThresMax Then
  242. lngCount = lngCount * 3 / 2
  243. Else
  244. lngCount = lngCount + mcExpandBigPer
  245. End If
  246. lMemCount = lngCount
  247. ReDim Preserve lMem(1 To lMemCount)
  248. ReLocaMem lngPreMemCount
  249. End Sub
  250.  
  251. Private Sub ReLocaMem(ByVal preMemCountTo As Long)
  252. '
  253. Dim memUsed() As Hs_DataType,lngUsedCount As Long
  254. Dim i As Long
  255. ReDim memUsed(1 To preMemCountTo + lMemUsedCount2)
  256. lngUsedCount = 0
  257. lMemUsedCount = 0
  258. For i = 1 To preMemCountTo
  259. If lMem(i).Used Then
  260. lngUsedCount = lngUsedCount + 1
  261. memUsed(lngUsedCount) = lMem(i)
  262. End If
  263. Next i
  264. For i = 1 To lMemUsedCount2
  265. lngUsedCount = lngUsedCount + 1
  266. memUsed(lngUsedCount) = lMem2(i)
  267. Next i
  268. ReDim lMem(1 To lMemCount)
  269. Erase lMem2
  270. lMemCount2 = 0
  271. lMemUsedCount2 = 0
  272. lMemUsedCount = 0
  273. Dim lngIdx As Long
  274. For i = 1 To lngUsedCount
  275. lngIdx = AlloMemIndex(memUsed(i).Key,False)
  276. If lngIdx > 0 Then
  277. lMem(lngIdx) = memUsed(i)
  278. lMem(lngIdx).Used = 1
  279. lMemUsedCount = lMemUsedCount + 1
  280. Else
  281. lMem2(-lngIdx) = memUsed(i)
  282. lMem2(-lngIdx).Used = 1
  283. lMemUsedCount2 = lMemUsedCount2 + 1
  284. End If
  285. Next i
  286. mTravIdxCurr = 0
  287. End Sub
  288.  
  289. Public Function IsKeyExist(ByVal Key As Long) As Boolean
  290. '
  291. Dim lngIdx As Long
  292. lngIdx = FindMemIndex(Key)
  293. IsKeyExist = (lngIdx <> 0)
  294. End Function
  295.  
  296. Public Sub startTraversal()
  297. '
  298. mTravIdxCurr = 1
  299. End Sub
  300.  
  301. Public Function NextItem(Optional ByRef rDataLong As Long,Optional ByRef rDataString As String,Optional ByRef rKey As Long,_
  302. Optional ByRef bRetNotValid As Boolean = False) As Long
  303. '
  304. Dim lngIdx As Long
  305. lngIdx = TraversalGetNextIdx
  306. If lngIdx > 0 Then
  307. With lMem(lngIdx)
  308. NextItem = .Data
  309. rDataLong = .DataLong
  310. rDataString = .DataString
  311. rKey = .Key
  312. End With
  313. ElseIf lngIdx < 0 Then
  314. With lMem2(-lngIdx)
  315. NextItem = .Data
  316. rDataLong = .DataLong
  317. rDataString = .DataString
  318. rKey = .Key
  319. End With
  320. Else
  321. bRetNotValid = True
  322. Exit Function
  323. End If
  324. End Function
  325.  
  326. Public Function NextData(Optional ByRef bRetNotValid As Boolean = False) As Long
  327. '
  328. Dim lngIdx As Long
  329. lngIdx = TraversalGetNextIdx
  330. If lngIdx > 0 Then
  331. NextData = lMem(lngIdx).Data
  332. ElseIf lngIdx < 0 Then
  333. NextData = lMem2(-lngIdx).Data
  334. Else
  335. bRetNotValid = True
  336. Exit Function
  337. End If
  338. End Function
  339.  
  340. Public Function NextDataLong(Optional ByRef bRetNotValid As Boolean = False) As Long
  341. '
  342. Dim lngIdx As Long
  343. lngIdx = TraversalGetNextIdx
  344. If lngIdx > 0 Then
  345. NextDataLong = lMem(lngIdx).DataLong
  346. ElseIf lngIdx < 0 Then
  347. NextDataLong = lMem2(-lngIdx).DataLong
  348. Else
  349. bRetNotValid = True
  350. End If
  351. End Function
  352.  
  353. Public Function NextDataString(Optional ByRef bRetNotValid As Boolean = False) As String
  354. '
  355. Dim lngIdx As Long
  356. lngIdx = TraversalGetNextIdx
  357. If lngIdx > 0 Then
  358. NextDataString = lMem(lngIdx).DataString
  359. ElseIf lngIdx < 0 Then
  360. NextDataString = lMem2(-lngIdx).DataString
  361. Else
  362. bRetNotValid = True
  363. Exit Function
  364. End If
  365. End Function
  366.  
  367. Public Function NextKey(Optional ByRef bRetNotValid As Boolean = False) As Long
  368. '
  369. Dim lngIdx As Long
  370. lngIdx = TraversalGetNextIdx
  371. If lngIdx > 0 Then
  372. NextKey = lMem(lngIdx).Key
  373. ElseIf lngIdx < 0 Then
  374. NextKey = lMem2(-lngIdx).Key
  375. Else
  376. bRetNotValid = True
  377. Exit Function
  378. End If
  379. End Function
  380.  
  381. Public Function GetDataArray(retData() As Long) As Long
  382. '
  383. Dim lngCount As Long
  384. Dim i As Long,j As Long
  385. lngCount = lMemUsedCount + lMemUsedCount2
  386. If lngCount <= 0 Then GetDataArray = 0: Exit Function
  387. ReDim retData(1 To lngCount)
  388. j = 1
  389. For i = 1 To lMemCount
  390. If lMem(i).Used Then
  391. retData(j) = lMem(i).Data
  392. j = j + 1
  393. End If
  394. Next i
  395. For i = 1 To lMemUsedCount2
  396. If lMem2(i).Used Then
  397. retData(j) = lMem2(i).Data
  398. j = j + 1
  399. End If
  400. Next i
  401. GetDataArray = lngCount
  402. End Function
  403.  
  404. Public Function GetDataLongArray(retDataLong() As Long) As Long
  405. '
  406. Dim lngCount As Long
  407. Dim i As Long,j As Long
  408. lngCount = lMemUsedCount + lMemUsedCount2
  409. If lngCount <= 0 Then GetDataLongArray = 0: Exit Function
  410. ReDim retDataLong(1 To lngCount)
  411. j = 1
  412. For i = 1 To lMemCount
  413. If lMem(i).Used Then
  414. retDataLong(j) = lMem(i).DataLong
  415. j = j + 1
  416. End If
  417. Next i
  418. For i = 1 To lMemUsedCount2
  419. If lMem2(i).Used Then
  420. retDataLong(j) = lMem2(i).DataLong
  421. j = j + 1
  422. End If
  423. Next i
  424. GetDataLongArray = lngCount
  425. End Function
  426.  
  427. Public Function GetDataStringArray(retDataString() As String) As Long
  428. '
  429. Dim lngCount As Long
  430. Dim i As Long,j As Long
  431. lngCount = lMemUsedCount + lMemUsedCount2
  432. If lngCount <= 0 Then GetDataStringArray = 0: Exit Function
  433. ReDim retDataString(1 To lngCount)
  434. j = 1
  435. For i = 1 To lMemCount
  436. If lMem(i).Used Then
  437. retDataString(j) = lMem(i).DataString
  438. j = j + 1
  439. End If
  440. Next i
  441. For i = 1 To lMemUsedCount2
  442. If lMem2(i).Used Then
  443. retDataString(j) = lMem2(i).DataString
  444. j = j + 1
  445. End If
  446. Next i
  447. GetDataStringArray = lngCount
  448. End Function
  449.  
  450.  
  451. Public Function GetKeyArray(retKeys() As Long) As Long
  452. '
  453. Dim lngCount As Long
  454. Dim i As Long,j As Long
  455. lngCount = lMemUsedCount + lMemUsedCount2
  456. If lngCount <= 0 Then GetKeyArray = 0: Exit Function
  457. ReDim retKeys(1 To lngCount)
  458. j = 1
  459. For i = 1 To lMemCount
  460. If lMem(i).Used Then
  461. retKeys(j) = lMem(i).Key
  462. j = j + 1
  463. End If
  464. Next i
  465. For i = 1 To lMemUsedCount2
  466. If lMem2(i).Used Then
  467. retKeys(j) = lMem2(i).Key
  468. j = j + 1
  469. End If
  470. Next i
  471. GetKeyArray = lngCount
  472. End Function
  473.  
  474. Public Sub Clear()
  475. '
  476. Erase lMem
  477. Erase lMem2
  478. lMemCount = 0: lMemUsedCount = 0
  479. lMemCount2 = 0: lMemUsedCount2 = 0
  480. lMemCount = mcIniMemSize
  481. ReDim lMem(1 To lMemCount)
  482. lMemUsedCount = 0
  483. lMemCount2 = 0
  484. lMemUsedCount2 = 0
  485. mTravIdxCurr = 0
  486. End Sub
  487.  
  488. Public Sub AlloMem(ByVal memSize As Long)
  489. '
  490. If memSize <= lMemUsedCount Or memSize > mcMaxItemCount Then Exit Sub
  491. Dim lngPreMemCount As Long
  492. lngPreMemCount = lMemCount
  493. lMemCount = memSize
  494. ReDim Preserve lMem(1 To lMemCount)
  495. ReLocaMem lngPreMemCount
  496. End Sub
  497.  
  498.  
  499. Private Function FindMemIndex(ByVal Key As Long) As Long
  500. '
  501. Const cMaxNumForSquare As Long = 46340
  502. Dim idxMod As Long,idxSqRev As Long
  503. Dim i As Long
  504. Dim keyToCalc As Long
  505. keyToCalc = Key
  506. If keyToCalc < 0 Then keyToCalc = 0 - keyToCalc
  507. ' 1
  508. idxMod = keyToCalc Mod lMemCount + 1
  509. If lMem(idxMod).Used And lMem(idxMod).Key = Key Then
  510. FindMemIndex = idxMod
  511. Exit Function
  512. End If
  513. ' 2
  514. If keyToCalc <= cMaxNumForSquare Then
  515. idxSq = (keyToCalc * keyToCalc) Mod lMemCount + 1
  516. Else
  517. idxSq = Sqr(keyToCalc) Mod lMemCount + 1
  518. End If
  519. If lMem(idxSq).Used And lMem(idxSq).Key = Key Then
  520. FindMemIndex = idxSq
  521. Exit Function
  522. End If
  523. ' 3
  524. idxModRev = lMemCount - idxMod + 1
  525. If lMem(idxModRev).Used And lMem(idxModRev).Key = Key Then
  526. FindMemIndex = idxModRev
  527. Exit Function
  528. End If
  529. ' 4
  530. idxSqRev = lMemCount - idxSq + 1
  531. If lMem(idxSqRev).Used And lMem(idxSqRev).Key = Key Then
  532. FindMemIndex = idxSqRev
  533. Exit Function
  534. End If
  535. ' 6
  536. Dim lngRetIdx As Long
  537. Dim idxMdSta As Long,idxMdEnd As Long
  538. idxMdSta = idxMod - mcSeqMax
  539. idxMdEnd = idxMod + mcSeqMax
  540. lngRetIdx = FindSeqIdx(Key,idxMdSta,idxMod - 1)
  541. If lngRetIdx > 0 Then
  542. FindMemIndex = lngRetIdx
  543. Exit Function
  544. End If
  545. lngRetIdx = FindSeqIdx(Key,idxMod + 1,idxMdEnd)
  546. If lngRetIdx > 0 Then
  547. FindMemIndex = lngRetIdx
  548. Exit Function
  549. End If
  550. ' 7
  551. Dim lngSqSta As Long,lngSqEnd As Long
  552. lngSqSta = idxSq - mcSeqMax
  553. lngSqEnd = idxSq + mcSeqMax
  554. If lngSqSta < 1 Then lngSqSta = 1
  555. If lngSqEnd > lMemCount Then lngSqEnd = lMemCount
  556. If lngSqEnd < idxMdSta Then
  557. lngRetIdx = FindSeqIdx(Key,lngSqSta,lngSqEnd)
  558. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  559. ElseIf lngSqEnd <= idxMdEnd Then
  560. If lngSqSta < idxMdSta Then
  561. lngSqEnd = idxMdSta - 1
  562. lngRetIdx = FindSeqIdx(Key,lngSqEnd)
  563. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  564. Else
  565. lngSqSta = 0: lngSqEnd = 0
  566. End If
  567. Else
  568. If lngSqSta > idxMdEnd Then
  569. lngRetIdx = FindSeqIdx(Key,lngSqEnd)
  570. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  571. ElseIf lngSqSta >= idxMdSta Then
  572. lngSqSta = idxMdEnd + 1
  573. lngRetIdx = FindSeqIdx(Key,lngSqEnd)
  574. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  575. Else
  576. lngRetIdx = FindSeqIdx(Key,idxMdSta - 1)
  577. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  578. lngRetIdx = FindSeqIdx(Key,idxMdEnd + 1,lngSqEnd)
  579. If lngRetIdx > 0 Then FindMemIndex = lngRetIdx: Exit Function
  580. End If
  581. End If
  582. For i = 1 To lMemUsedCount2
  583. If lMem2(i).Used And lMem2(i).Key = Key Then FindMemIndex = -i: Exit Function
  584. Next i
  585. FindMemIndex = 0
  586. End Function
  587.  
  588. Private Function FindSeqIdx(ByVal Key As Long,ByVal fromIndex As Long,fCt As Long
  589. If fromIndex < 1 Then fromIndex = 1
  590. If toIndex > lMemCount Then toIndex = lMemCount
  591. For i = fromIndex To toIndex
  592. If lMem(i).Used And lMem(i).Key = Key Then
  593. FindSeqIdx = 1
  594. Exit Function
  595. End If
  596. Next i
  597. FindSeqIdx = 0
  598. End Function
  599.  
  600. Private Function TraversalGetNextIdx() As Long
  601. '
  602. Dim lngRetIdx As Long
  603. If mTravIdxCurr > lMemCount Or -mTravIdxCurr > lMemCount2 Or mTravIdxCurr = 0 Then
  604. lngRetIdx = 0
  605. Exit Function
  606. End If
  607. If mTravIdxCurr > 0 Then
  608. Do Until lMem(mTravIdxCurr).Used
  609. mTravIdxCurr = mTravIdxCurr + 1
  610. If mTravIdxCurr > lMemCount Then Exit Do
  611. Loop
  612. If mTravIdxCurr > lMemCount Then
  613. If lMemCount2 > 0 Then
  614. mTravIdxCurr = -1
  615. Else
  616. lngRetIdx = 0
  617. TraversalGetNextIdx = lngRetIdx
  618. Exit Function
  619. End If
  620. Else
  621. lngRetIdx = mTravIdxCurr
  622. mTravIdxCurr = mTravIdxCurr + 1
  623. If mTravIdxCurr > lMemCount Then If lMemCount2 > 0 Then mTravIdxCurr = -1
  624. TraversalGetNextIdx = lngRetIdx
  625. Exit Function
  626. End If
  627. End If
  628. If mTravIdxCurr < 0 Then
  629. Do Until lMem2(-mTravIdxCurr).Used
  630. mTravIdxCurr = mTravIdxCurr - 1
  631. If -mTravIdxCurr > lMemCount2 Then Exit Do
  632. Loop
  633. If -mTravIdxCurr > lMemCount2 Then
  634. lngRetIdx = 0
  635. Else
  636. lngRetIdx = mTravIdxCurr
  637. mTravIdxCurr = mTravIdxCurr - 1
  638. End If
  639. TraversalGetNextIdx = lngRetIdx
  640. End If
  641. End Function
  642.  
  643. Private Sub Class_Initialize()
  644. '
  645. lMemCount = mcIniMemSize
  646. ReDim lMem(1 To lMemCount)
  647. lMemUsedCount = 0
  648. lMemCount2 = 0
  649. lMemUsedCount2 = 0
  650. End Sub
  651.  
  652. Private Sub Class_Terminate()
  653. '
  654. Erase lMem
  655. Erase lMem2
  656. lMemCount = 0: lMemUsedCount = 0
  657. lMemCount2 = 0: lMemUsedCount2 = 0
  658. End Sub
  659.  
  660. Public Property Get Count() As Long
  661. '
  662. Count = lMemUsedCount + lMemUsedCount2
  663. End Property

猜你在找的VB相关文章