-
vb教程之用VB实现双向循环链表
作者:zgl
邮箱:yoshiro_gl@21cn.com
发现大多数人对VB中应用指针不太了解,作一些说明。
VB的指针挺简单的,用着也很方便,其实对象变量就可以看成是指针,当你用Set A=Obj时,A就是指向Obj的地址。不用API就可以,当然用API可以实现更为高级的结构。
给一个例子,一个用VB实现的双向循环链表。有链表的生成,删除和结点的插入。
先定义一个结点类,类名为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
再添加一个窗体,窗体上添加两个列表框,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
一个双向循环链表就形成了,List1中是正向遍历的结果,List2中是反向遍历的结果。类的构造器Class_Initialize()过程,类的析构Class_Termainate()过程,结点内存的分配和回收都由类自身完成,还有多态,pHead As Object;Set pHead = New Node;Set pHead.pPrev = p;指向基类的指针指向了子类,并调用了子类的属性,是不是挺像C++的代码?
链表有了,二叉树,由临接表构成的图等数据结构都很容易实现了吧,实际上用VB能构造很复杂的数据结构,上面的代码只是简单的示例,实际可以做的更完善。
另外,VB6也能够生成真实的地址。三种未正式公布的VBA方法VarPtr,ObjPtr,和StrPtr(实际上是指向运行DLL同一入口的三个不同的类型库别名)就可以用来建立指针,使用address=ObjPtr(Obj)就可以获得对象的地址,Obj为需要地址的对象,而Address为一个long型变量,其中放置了对象的地址,使用VarPtr(产生变量的地址和UDT),StrPtr(产生字符串的地址)和ObjPtr(产生对象的地址)可以构造真实的,非常复杂的数据结构。
上面三个方法并没有在Microsoft的正式文档资料中公布(包括MSDN),但查看VB6的基本动态运行库MSVBVM60.DLL可以发现这三个方法:
[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);
类似这样的隐藏方法还有不少,实际上VB6的功能是相当强大的,但大家又真正了解VB6多少呢?
邮箱:yoshiro_gl@21cn.com
发现大多数人对VB中应用指针不太了解,作一些说明。
VB的指针挺简单的,用着也很方便,其实对象变量就可以看成是指针,当你用Set A=Obj时,A就是指向Obj的地址。不用API就可以,当然用API可以实现更为高级的结构。
给一个例子,一个用VB实现的双向循环链表。有链表的生成,删除和结点的插入。
先定义一个结点类,类名为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
再添加一个窗体,窗体上添加两个列表框,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
一个双向循环链表就形成了,List1中是正向遍历的结果,List2中是反向遍历的结果。类的构造器Class_Initialize()过程,类的析构Class_Termainate()过程,结点内存的分配和回收都由类自身完成,还有多态,pHead As Object;Set pHead = New Node;Set pHead.pPrev = p;指向基类的指针指向了子类,并调用了子类的属性,是不是挺像C++的代码?
链表有了,二叉树,由临接表构成的图等数据结构都很容易实现了吧,实际上用VB能构造很复杂的数据结构,上面的代码只是简单的示例,实际可以做的更完善。
另外,VB6也能够生成真实的地址。三种未正式公布的VBA方法VarPtr,ObjPtr,和StrPtr(实际上是指向运行DLL同一入口的三个不同的类型库别名)就可以用来建立指针,使用address=ObjPtr(Obj)就可以获得对象的地址,Obj为需要地址的对象,而Address为一个long型变量,其中放置了对象的地址,使用VarPtr(产生变量的地址和UDT),StrPtr(产生字符串的地址)和ObjPtr(产生对象的地址)可以构造真实的,非常复杂的数据结构。
上面三个方法并没有在Microsoft的正式文档资料中公布(包括MSDN),但查看VB6的基本动态运行库MSVBVM60.DLL可以发现这三个方法:
[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);
类似这样的隐藏方法还有不少,实际上VB6的功能是相当强大的,但大家又真正了解VB6多少呢?
最新更新
python爬虫及其可视化
使用python爬取豆瓣电影短评评论内容
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
uniapp/H5 获取手机桌面壁纸 (静态壁纸)
[前端] DNS解析与优化
为什么在js中需要添加addEventListener()?
JS模块化系统
js通过Object.defineProperty() 定义和控制对象
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比