用VB实现循环队列算法
|
admin
2013年11月28日 11:48
本文热度 4773
|
在日常代码编制时,许多人会忽略一些最基本的算法,导致代码冗余,思路不清楚。我曾经至少两次在CSDN里遇到这类问题:我想在页面的右边显示一个列表,列表长度为20,新加入一个用户后,显示在列表开头,再加入的用户,显示在这个用户的下边,当用户数量超过20后,挤掉最前面的那一位,第二位加入的用户成了第一位,依次循环,保证列表最多显示20位用户。当然,实际问题可能与此有些出入,比如Coder是想显示网友们最近选择的歌曲列表,但实际意思差不多。
面对这个问题,大多数朋友会想到使用数据。其实,这完全是一个队列,只不过,这个队列可以循环使用,在加入队列元素时,如果超过长度,会自动挤掉最先加入的。如果能够用代码直接实现,为什么要用数据库呢?考虑一下,为了提高网站性能,我们绞尽脑汁,却往往因为思路的偏差,导致性能降低。
那么,在VB中如何实现可循环的队列呢?
为此,我编写了一个循环队列类,以满足上述需要,同时为了方便在HTML、ASP、WSH的VBScript脚本语言环境中使用,该类未声明任何数据类型。
首先看一下该循环队列类的源代码:
'* ************************************************************** *
'* 程序名称:Queue.cls
'* 程序功能:一个VB循环队列类
'* 作者:lyserver
'* 联系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
'Class Queue '在ASP、WSH、HTML的VBScript脚本中使用时需加此句
Dim m_Queue() '队列
Dim m_RetQueue() '队列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '队列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '队列默认大小为20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'获得队列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'设置队列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入队列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '队列已满,挤掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndex = m_WriteIndex + 1
End Sub
'删除队列元素(按队列原则,实际上是删除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '将此变量置为未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空队列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'获得队列数组
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
GetQueue = m_RetQueue
End Property
'End Class '在ASP、WSH、HTML的VBScript脚本中使用时需加此句
'* ************************************************************** *
'* 程序名称:Queue.cls
'* 程序功能:一个VB循环队列类
'* 作者:lyserver
'* 联系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
'Class Queue '在ASP、WSH、HTML的VBScript脚本中使用时需加此句
Dim m_Queue() '队列
Dim m_RetQueue() '队列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '队列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '队列默认大小为20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'获得队列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'设置队列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入队列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '队列已满,挤掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndex = m_WriteIndex + 1
End Sub
'删除队列元素(按队列原则,实际上是删除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '将此变量置为未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空队列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'获得队列数组
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
n = n + 1
Next
GetQueue = m_RetQueue
End Property
'End Class '在ASP、WSH、HTML的VBScript脚本中使用时需加此句
然后,我们再来看一下在VB中如何使用此类:
Sub main()
Dim objQueue
Dim i, nLen
Set objQueue = New Queue
'将队列长度置为5
nLen = 5
objQueue.MaxLen = nLen
'向队列插入元素(不超过队列长度)
For i = 1 To nLen
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'清空队列后重新插入元素(超过队列长度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'删除队列元素
objQueue.Delete
'显示结果
DisplayQueue objQueue
End Sub
Private Sub DisplayQueue(qu)
Dim v(), i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
Debug.Print "第" & i + 1 & "个元素的值:", v(i)
Next
Debug.Print "------显示完毕------"
End Sub
Sub main()
Dim objQueue
Dim i, nLen
Set objQueue = New Queue
'将队列长度置为5
nLen = 5
objQueue.MaxLen = nLen
'向队列插入元素(不超过队列长度)
For i = 1 To nLen
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'清空队列后重新插入元素(超过队列长度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'删除队列元素
objQueue.Delete
'显示结果
DisplayQueue objQueue
End Sub
Private Sub DisplayQueue(qu)
Dim v(), i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
Debug.Print "第" & i + 1 & "个元素的值:", v(i)
Next
Debug.Print "------显示完毕------"
End Sub
看过了VB使用方法后,我们再来看一下在HTML的VBScript脚本中如何使用,需要注意的是,要想测试结果,必须将以下代码复制到记事本后另存为扩展名为html或htm的文件,然后使用IE打开,对于类代码,读者也可以单独取出来存为vbs文件,然后html里包含它就可以了。至于ASP,思路与此完全一样。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>新建网页 1</title>
</head>
<body>
</body>
</html>
<mce:script language=vbscript><!--
Option Explicit
'* ************************************************************** *
'* 程序名称:Queue.cls
'* 程序功能:一个VB循环队列类
'* 作者:lyserver
'* 联系方式:http://blog.csdn.net/lyserver
'* ************************************************************** *
Class Queue
Dim m_Queue() '队列
Dim m_RetQueue() '队列返回值
Dim m_ReadIndex '列首偏移索引
Dim m_WriteIndex '元素插入偏移索引
Dim m_MaxLen '队列最大尺寸
Private Sub Class_Initialize()
m_ReadIndex = 0
m_WriteIndex = 0
m_MaxLen = 20 '队列默认大小为20
ReDim m_Queue(m_MaxLen - 1)
End Sub
Private Sub Class_Terminate()
Erase m_Queue
Erase m_RetQueue
End Sub
'获得队列大小
Public Property Get MaxLen()
MaxLen = m_MaxLen
End Property
'设置队列大小
Public Property Let MaxLen(ByVal NewValue)
If NewValue > 0 Then
m_MaxLen = NewValue
ReDim m_Queue(m_MaxLen)
End If
End Property
'插入队列元素
Public Sub Insert(ByVal v)
If m_WriteIndex = m_MaxLen Then '队列已满,挤掉最先插入的元素
m_WriteIndex = 0
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End If
m_Queue(m_WriteIndex) = v
m_WriteIndexm_WriteIndex = m_WriteIndex + 1
End Sub
'删除队列元素(按队列原则,实际上是删除最先插入的元素)
Public Sub Delete()
Dim vTemp
m_Queue(m_ReadIndex) = vTemp '将此变量置为未初始化
m_ReadIndex = (m_ReadIndex + 1) Mod m_MaxLen
End Sub
'清空队列
Public Sub Clear()
ReDim m_Queue(m_MaxLen)
m_WriteIndex = 0
m_ReadIndex = 0
End Sub
'获得队列数组
Public Property Get GetQueue()
Dim i, n
n = 0
ReDim m_RetQueue(m_MaxLen)
For i = m_ReadIndex To m_MaxLen - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
nn = n + 1
Next
For i = 0 To m_ReadIndex - 1
If IsEmpty(m_Queue(i)) Then Exit For
m_RetQueue(n) = m_Queue(i)
nn = n + 1
Next
GetQueue = m_RetQueue
End Property
End Class
Sub window_onload
Dim objQueue
Dim i, nLen
Set objQueue=New Queue
'将队列长度置为5
nLen = 5
objQueue.MaxLen = nLen
'向队列插入元素(不超过队列长度)
For i = 1 To nLen
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'清空队列后重新插入元素(超过队列长度)
objQueue.Clear
For i = 1 To nLen + 1
objQueue.Insert i
Next
'显示结果
DisplayQueue objQueue
'删除队列元素
objQueue.Delete
'显示结果
DisplayQueue objQueue
End Sub
Sub DisplayQueue(qu)
Dim v,i
v = qu.GetQueue
For i = 0 To qu.MaxLen - 1
If IsEmpty(v(i)) Then Exit For
document.write "第" & i + 1 & "个元素的值:" & v(i) & "<br>"
Next
document.write "------显示完毕------<br>"
End Sub
// --></mce:script>
该文章在 2013/11/28 11:48:35 编辑过