链表, 底层以数组来实现, 记得原来Java里面好像有ArrayList和Linketlist. 这个就是ArrayList. 还没有经过严格的测试, 你要是发现bug记得留言.

因为代码也是有点长我就分为两个部分, 一个是ArrayList的实现, 我Link成了lib文件, 以后都很方便添加到新的工程. 另外我用的ml 和Link都是9.0版本的, 和masm32包里面带的又些许地方会不兼容. 很明显9.0搞的库没法在6.13下面使用. 不过没有关系, 代码我贴出来了.单击下载ArrayList

库函数部分有点多, 不分析了. 其实我发现我现在的表述能力在退步. 所以自己分析代码吧. 有问题, 留言就可以了..先看看使用部分的代码

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
;***************************************************************************
	;基于数组实现的链表(测试程序)
	;编译环境 masm32 + nmake windows xp sp3 TAB=8
	;作者: Joen
	;日期: 2011年5月30日12:07:11
	;出处: http://JoenChen.com(Joen专栏)
	;有问题可以在网页留言或者发Email:[email protected]
;***************************************************************************	
	Include masm32rt.inc
	Include	ArrayList.inc
DATANODE	Struct
	SzString	byte	128	dup(?)
DATANODE 	Ends
	.code
;***************************************************************************
	;链表比较函数
	;_lpDataNode1 < _lpDataNode2 返回-1
	;_lpDataNode1 > _lpDataNode2 返回1
	;_lpDataNode1 == _lpDataNode2 返回0
;***************************************************************************
_Compare	Proc	_lpDataNode1:dword, _lpDataNode2:dword
	mov	ebx, _lpDataNode1
	mov	esi,_lpDataNode2
	assume	ebx:ptr DATANODE, esi:ptr DATANODE

	Invoke	lstrcmp,ebx, esi
	assume	ebx:ptr nothing, esi:ptr nothing
	ret
_Compare 	Endp
;***************************************************************************
	;遍历函数原型范例ArrayList在需要比较的时候会调用此函数, 
	;_lpDataNode:目前遍历到的节点
	;_dwSize	:目前已经遍历了几个
	;_dwIsOver	:如果遍历结束时会调用此函数(用户函数应当首先判断此值)
_Iterator	Proc	_lpDataNode:dword, _dwSize:dword, _dwIsOver:dword

;===========================================================================
	;最后的清理工作, 不应该再访问_lpDataNode和_dwSize
	.if	_dwIsOver	
		Invoke	crt_printf, cfm$( "遍历结束\n" )
		ret
	.Endif
;===========================================================================
	;这里可以对节点做一些操作(修改也是允许的)
	mov	ebx, _lpDataNode
	;int	3
	Invoke	crt_printf, cfm$( "%s\t" ), addr [ebx+DATANODE.SzString]
	
	mov	eax, _dwSize
	mov	ecx, 4
	cdq
	div	ecx
;===========================================================================
	;如果需要目前遍历到什么位置(这里也是可以)	
	.if	!edx
		Invoke	crt_printf, cfm$( "\n" ), [ebx+DATANODE.SzString]	
	.Endif
	ret
_Iterator 	Endp
;***************************************************************************
	;链表测试函数
;***************************************************************************
Jmain	Proc
	local	_StData:DATANODE
	local	_lpArrayList:dword
	
;===========================================================================
	;初始化链表	
	Invoke	_ArrayListInit, addr _lpArrayList, offset _Compare,
		 offset _Iterator, 2, sizeof DATANODE, 1
	.if	!eax
		Invoke	crt_printf, cfm$( "初始化链表失败, %s\n" ), LastError$()
		ret
	.Endif
;===========================================================================	
	;插入数据到ArrayList
	Invoke	lstrcpy, addr _StData.SzString, cfm$( "hello" )
	Invoke	_ArrayListInsert,addr _lpArrayList,addr  _StData
	.if	eax
		Invoke	crt_printf, cfm$( "插入元素到链表成功\x\n" )	
	.Else
		Invoke	crt_printf, cfm$( "插入元素到链表失败 %s\n" ), LastError$()		
	.Endif
	Invoke	_ArrayListIterator, addr _lpArrayList
;===========================================================================
	;再插入一个元素
	Invoke	lstrcpy, addr _StData.SzString, cfm$( "nihao" )
	Invoke	_ArrayListInsert,addr _lpArrayList,addr  _StData
	.if	eax
		Invoke	crt_printf, cfm$( "插入元素到链表成功\x\n" )
	.Else
		Invoke	crt_printf, cfm$( "插入元素到链表失败 %s\n" ), LastError$()		
	.Endif
	Invoke	_ArrayListIterator, addr _lpArrayList
;===========================================================================
	;删除加插入ArrayList数据	
	Invoke	lstrcpy, addr _StData.SzString, cfm$( "hello" )
	Invoke	_ArrayListDel, addr _lpArrayList, addr _StData
	.if	eax
		Invoke	crt_printf, cfm$( "删除元素成功\x\n" )
	.Else
		Invoke	crt_printf, cfm$( "删除元素失败 %s\n" ), LastError$()
	.Endif
	Invoke	_ArrayListIterator, addr _lpArrayList
;===========================================================================
	;查找某个数据元素	
	Invoke	lstrcpy, addr _StData.SzString, cfm$( "nihao" )
	Invoke	_ArrayListFind, addr _lpArrayList, addr _StData
	.if	!eax
		Invoke	crt_printf, cfm$( "未能够找到数据\n" )
	.Else
		Invoke	crt_printf, cfm$( "找到该数据指针是:%p 数据是:%d\n" ), eax, dword ptr [eax]
	.Endif
;===========================================================================
	;别忘记释放数组
	Invoke	_ArrayListClean, addr _lpArrayList
	
	Invoke	crt_system, cfm$( "pause" )
;===========================================================================	
	ret
Jmain 	Endp
End	Jmain

代码比较简单, 我主要说说Compare和Iterator, 在初始化链表的时候应该传递这两个函数指针给库, Compare是比较函数怎么算大怎么算小. 你说了算. 还有Iterator, 怎么遍历. 还是你说了算, 呵呵 是不是有点多态的感觉了!

代码都在这里了, 比较简单也没有什么难点, 稍微看下就明白了. 这个数组实现的应该是比较给力了, 以后不管什么类型都可以用这个链表来存放, 也算一定程度的多态, 我在看Objasm32的实现, 发现 作者大量的使用了这种手段, 牛人就是牛人这是代码的使用部分, 库函数部分我在开头提供了下载. 在网页上看代码并不是什么好主意, 我就不贴了. 如果发现有bug一定要留言. 我也没有怎么测试这 个代码, 难免有些情况考虑不到..