用VB完成雙向循環(huán)鏈表
發(fā)表時(shí)間:2024-02-25 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]作者:zgl郵箱:yoshiro_gl@21cn.com 發(fā)現(xiàn)大多數(shù)人對(duì)VB中應(yīng)用指針不太了解,作一些說(shuō)明! B的指針挺簡(jiǎn)單的,用著也很方便,其實(shí)對(duì)象變量就可以看成是指針,當(dāng)你用Set A=Obj時(shí),A就是指向Obj的地址。不用API就可以,當(dāng)然用API可以實(shí)現(xiàn)更為高級(jí)的結(jié)構(gòu)! 〗o一個(gè)例子...
作者:zgl
郵箱:yoshiro_gl@21cn.com
發(fā)現(xiàn)大多數(shù)人對(duì)VB中應(yīng)用指針不太了解,作一些說(shuō)明。
VB的指針挺簡(jiǎn)單的,用著也很方便,其實(shí)對(duì)象變量就可以看成是指針,當(dāng)你用Set A=Obj時(shí),A就是指向Obj的地址。不用API就可以,當(dāng)然用API可以實(shí)現(xiàn)更為高級(jí)的結(jié)構(gòu)。
給一個(gè)例子,一個(gè)用VB實(shí)現(xiàn)的雙向循環(huán)鏈表。有鏈表的生成,刪除和結(jié)點(diǎn)的插入。
先定義一個(gè)結(jié)點(diǎn)類(lèi),類(lèi)名為Node,代碼為:
Option Explicit
Public pNext As Node
Public pPrev As Node
Public data As Single
Private Sub Class_Initialize()
Set pNext = Nothing
Set pPrev = Nothing
End Sub
Private Sub Class_Terminate()
Set pNext = Nothing
Set pPrev = Nothing
End Sub
再添加一個(gè)窗體,窗體上添加兩個(gè)列表框,list1和list2,窗體的代碼為:
Option Explicit
Private pHead As Object
Private pV As Object
Private Sub Form_Load()
Dim i As Integer
Set pHead = New Node
Call CreateLinkList
Call InsertNode(pHead, 503)
Call InsertNode(pHead, 1.875)
Call InsertNode(pHead, -3.675)
For i = 1 To 100
Call InsertNode(pHead, -1 * i)
Next
Call PrintList
Call DeleteList
End Sub
Public Sub CreateLinkList()
Dim p As Node
Dim nLoop As Integer
Static pLast As Node
pHead.data = 0
Set pLast = pHead
For nLoop = 1 To 501
Set p = New Node
p.data = nLoop
Set pLast.pNext = p
Set p.pPrev = pLast
Set pLast = p
Next
Set pLast = Nothing
Set p.pNext = pHead
Set pHead.pPrev = p
Exit Sub
End Sub
Public Sub PrintList()
List1.AddItem "Forwards"
Set pV = pHead
Do
List1.AddItem pV.data
Set pV = pV.pNext
Loop While Not pV Is pHead
List2.AddItem "Backwards"
Set pV = pHead.pPrev
Do
List2.AddItem pV.data
Set pV = pV.pPrev
Loop While Not pV Is pHead.pPrev
End Sub
Public Sub DeleteList()
Dim p As Node
Set pV = pHead
Do
Set pV = pV.pNext
Set p = pV.pPrev
If Not p Is Nothing Then
Set p.pNext = Nothing
Set p.pPrev = Nothing
End If
Set p = Nothing
Loop While Not pV.pNext Is Nothing
Set pV = Nothing
Set pHead = Nothing
End Sub
Public Sub InsertNode(head As Node, data As Single)
Dim p As New Node, q As Node, prev As Node
p.data = data
Set q = head
Set prev = head.pPrev
While ((q.data < p.data) And Not q.pNext Is head)
Set q = q.pNext
Set prev = prev.pNext
Wend
If Not q.pNext Is head Then
Set p.pNext = q
Set p.pPrev = prev
Set prev.pNext = p
Set q.pPrev = p
If q Is head Then
Set head = p
End If
Else
Set p.pNext = head
Set p.pPrev = q
Set head.pPrev = p
Set q.pNext = p
End If
End Sub
一個(gè)雙向循環(huán)鏈表就形成了,List1中是正向遍歷的結(jié)果,List2中是反向遍歷的結(jié)果。類(lèi)的構(gòu)造器Class_Initialize()過(guò)程,類(lèi)的析構(gòu)Class_Termainate()過(guò)程,結(jié)點(diǎn)內(nèi)存的分配和回收都由類(lèi)自身完成,還有多態(tài),pHead As Object;Set pHead = New Node;Set pHead.pPrev = p;指向基類(lèi)的指針指向了子類(lèi),并調(diào)用了子類(lèi)的屬性,是不是挺像C++的代碼?
鏈表有了,二叉樹(shù),由臨接表構(gòu)成的圖等數(shù)據(jù)結(jié)構(gòu)都很容易實(shí)現(xiàn)了吧,實(shí)際上用VB能構(gòu)造很復(fù)雜的數(shù)據(jù)結(jié)構(gòu),上面的代碼只是簡(jiǎn)單的示例,實(shí)際可以做的更完善。
另外,VB6也能夠生成真實(shí)的地址。三種未正式公布的VBA方法VarPtr,ObjPtr,和StrPtr(實(shí)際上是指向運(yùn)行DLL同一入口的三個(gè)不同的類(lèi)型庫(kù)別名)就可以用來(lái)建立指針,使用address=ObjPtr(Obj)就可以獲得對(duì)象的地址,Obj為需要地址的對(duì)象,而Address為一個(gè)long型變量,其中放置了對(duì)象的地址,使用VarPtr(產(chǎn)生變量的地址和UDT),StrPtr(產(chǎn)生字符串的地址)和ObjPtr(產(chǎn)生對(duì)象的地址)可以構(gòu)造真實(shí)的,非常復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。
上面三個(gè)方法并沒(méi)有在Microsoft的正式文檔資料中公布(包括MSDN),但查看VB6的基本動(dòng)態(tài)運(yùn)行庫(kù)MSVBVM60.DLL可以發(fā)現(xiàn)這三個(gè)方法:
[entry(0x60000006),hidden]
long __stdcall VarPtr([in]void* Ptr);
[entry(0x60000007),hidden]
long __stdcall StrPtr([in]BSTR Ptr);
[entry(0x60000008),hidden]
long __stdcall ObjPtr([in]IUnknown* Ptr);
類(lèi)似這樣的隱藏方法還有不少,實(shí)際上VB6的功能是相當(dāng)強(qiáng)大的,但大家又真正了解VB6多少呢?