AS2.0中实现数据结构-哈希表
在游戏制作中我们经常需要存储一些离散的对象数据,比如道具箱里的道具,经常需要执行插入和删除操作,而且道具之间没有联系是无序排列的.有些人会说直接用数组不就得了,但是有大量数据存储时的数组的删除插入操作的效率是很低的。
因此我们需要哈希表这样的可以提供快速的插入和删除,查找操作的数据结构,不论哈希表中有多少数据,插入和删除操作只需要接近常量的时间:即O(1)的时间级。
既然这么好那么我们的AS可以实现吗?当然可以!AS发展到AS2.0,已经成为在语法上更接近于Java + Pascal的面向对象的语言.如今,伴随着Flash8的发行,使得这种脚本语言添加了运行速度更加快捷,后台技术连接的更加方便等优点.因此我们完全可以用AS来实现一些常用数据结构。
首先我们先要实现有序链表,顾名思义,链表就是一种像链一样的数据结构,类似数组,但是不同的是链表每个节点一般都至少包括一个数据项和一个指向下个节点的指针,而且有序链表的数据是按顺序排列的。
建议大家把类都放到包里,这样便于以后查找和使用,这里我把这些类放在名为util的包里面.
-
有序链表的实现:
-
链表结点类:
class util.Link { public var iData; // data item(key) public var dData; public var next:util.Link; // next link in list // ------------------------------------------------------------ public function Link(id,dd) // constructor { iData = id; // (’next’ is automatically dData = dd; } // set to null) // ------------------------------------------------------------ public function displayLink():Void // display ourself { trace("{" + iData + "," +dData+ "} "); } } // end class Link 有序链表类: import util.Link;//注意要导入我们前边的Link类! class util.SortedList { private var first:Link; // ref to first list item // ------------------------------------------------------------ public function SortedList() // constructor { first = null; } // ------------------------------------------------------------ public function insert(theLink:Link):Void // insert link, in order { var key = theLink.iData; var previous:Link = null; // start at first var current:Link = first; // until end of list, while(current != null && key > current.iData) { // or current > key, previous = current; current = current.next; // go to next item } if(previous==null) // if beginning of list, first = theLink; // first --> new link else // not at beginning, previous.next = theLink; // prev --> new link theLink.next = current; // new link --> current } // end insert() public function deleteD(key):Void // delete link { // (assumes non-emptylist) var previous:Link = null; // start at first var current:Link = first; // until end of list, while(current != null && key != current.iData) { // or key == current, previous = current; current = current.next; // go to next link } // disconnect link if(previous==null) // if beginning of list first = first.next; // delete first link else // not at beginning previous.next = current.next; // delete currentlink } // end delete() // ------------------------------------------------------------ public function find(key):Link // find link { var current:Link = first; // start at first // until end of list, while(current != null && current.iData <= key) { // or key too small, if(current.iData == key) // is this the link? return current; // found it, return link current = current.next; // go to next item } return null; // didn’t find it } // end find() // ------------------------------------------------------------ public function displayList():Void { trace("List (first-->last): "); var current:Link = first; // start at beginning of list while(current != null) // until end of list, { current.displayLink(); // print data current = current.next; // move to next link } trace(""); } } // end class SortedList
-
哈希表的实现:
-
哈希表类:
import util.Link;//注意要导入我们前边的Link类! import util.SortedList;//注意要导入我们前边的SortedList类! class util.HashTable { private var hashArray:Array; // array of lists private var arraySize:Number; // ------------------------------------------------------------ public function HashTable(size:Number) // constructor { arraySize = size; hashArray = new Array(arraySize); // create array for(var j=0; j<arraySize; j++) // fill array hashArray[j] = new SortedList(); // with lists } // ------------------------------------------------------------ public function displayTable():Void { for(var j=0; j<arraySize; j++) // for each cell, { trace(j + ". "); // display cell number hashArray[j].displayList(); // display list } } // ------------------------------------------------------------ public function hashFunc(key):Number // hash function { return key % arraySize; } // ------------------------------------------------------------ public function insert(theLink:Link):Void // insert a link { var key = theLink.iData; var hashVal = hashFunc(key); // hash the key hashArray[hashVal].insert(theLink); // insert at hashVal } // end insert() // ------------------------------------------------------------ public function deleteD(key):Void // delete a link { var hashVal = hashFunc(key); // hash the key hashArray[hashVal].deleteD(key); // delete link } // end delete() // ------------------------------------------------------------ public function find(key):Link // find link { var hashVal = hashFunc(key); // hash the key var theLink:Link = hashArray[hashVal].find(key); // get link return theLink; // return link } // ------------------------------------------------------------ }// end class HashTable
哈希表的哈希函数hashFunc(key)我们可以自行设计,我这里用了最简单的求模运算。哈希函数设计的好坏决定着哈希表的各项操作的效率。
-
哈希表的使用:
var itemTable = new HashTable(6);//声明一个哈希表对象,并定义空间大小为6; var item:Array = new Array("cupper","herb","knife","tinymedal","cloth","milk"); for (var i = 0; i<6; i++) { var tlink = new Link(6 * i,item[i]);//声明一个链表结点,第一个参数为key值,第二个为想要存入的对象,这里是道具名; itemTable.insert(tlink); } //将结点插入哈希表; }; itemTable.displayTable();//展示哈希表中的数据; //大家可以试试其他查找和删除操作;