链表集合类简介及对比Array:
基于链表实现的列表集合
在执行向头部插入(unshift)或删除(removeFirst)和两个集合合并(addLinkedList)或插入(setLinkedList)时速度远远高于Array
在执行截取(interceptList)时速度远高于Array
在执行随机插入(set)和替换(replace)时整体速度高于Array
在执行末尾部插入或删除时理论速度与Array基本相同,但在peopleCode中速度会低于Array
执行倒序(Reverse)时速度稍低于Array
随机取数和使用for遍历时速度远低于Array,遍历时应使用迭代遍历或指针遍历方式
具体区别可参阅Java的ArrayList和LinkedList区别的相关文献。
链表集合节点使用any数组,数组第一位为上一个节点,第二位为本节点,第三位为下一节点
本来节点使用实体类实现,但是发现peopleCode对自定义class操作没有对any数组操作快。
peopleCode实现代码如下:
/* CSQ ADD 链表集合类
基于链表实现的列表集合
在执行向头部插入(unshift)或删除(removeFirst)和两个集合合并(addLinkedList)或插入(setLinkedList)时速度远远高于Array
在执行截取(interceptList)时速度远高于Array
在执行随机插入(set)和替换(replace)时整体速度高于Array
在执行末尾部插入或删除时速度与Array基本相同,但在peopleCode中速度会低于Array
执行倒序(Reverse)时速度稍低于Array
随机取数和使用for遍历时速度远低于Array,遍历时应使用迭代遍历或指针遍历方式
*/
/*
链表集合节点使用any数组,数组第一位为上一个节点,第二位为本节点,第三位为下一节点。
本来节点使用实体类实现,但是发现peopleCode对自定义class操作没有对any数组操作快。
*/
class LinkedList
/* 集合长度 */
property integer len get;
/* 添加元素到集合末尾 */
method add(&element As any);
/* 添加节点到集合末尾。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method addNode(&node As array);
/* 添加集合到集合末尾。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method addLinkedList(&linkedList As GT_COMMON:UTIL:LinkedList);
/* 添加元素到集合前面 */
method unshift(&element As any);
/* 添加节点到集合前面。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method unshiftNode(&node As array);
/* 添加集合到集合前面。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method unshiftLinkedList(&linkedList As GT_COMMON:UTIL:LinkedList);
/* 插入元素到集合&index位置 */
method set(&index As integer, &element As any);
/* 插入节点到集合&index位置。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method setNode(&index As integer, &node As array);
/* 插入集合到集合&index位置。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method setLinkedList(&index As integer, &linkedList As GT_COMMON:UTIL:LinkedList);
/* 获取集合内第&index个元素 */
method get(&index As integer) Returns any;
/* 获取集合内第&index个节点 */
method getNode(&index As integer) Returns array;
/* 获取集合内第一个元素 */
method getFirst() Returns any;
/* 获取集合内第一个节点 */
method getFirstNode() Returns array;
/* 获取集合内最后一个元素 */
method getLast() Returns any;
/* 获取集合内最后一个节点 */
method getLastNode() Returns array;
/* 替换&startIndex到&endIndex元素为&element */
method replace(&startIndex As integer, &endIndex As integer, &element As any);
/* 替换&startIndex到&endIndex节点为&element。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method replaceNode(&startIndex As integer, &endIndex As integer, &node As array);
/* 替换&startIndex到&endIndex节点为&linkedList。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method replaceToLinkedList(&startIndex As integer, &endIndex As integer, &linkedList As GT_COMMON:UTIL:LinkedList);
/* 截取列表,保留从&startIndex到&endIndex的元素 */
method interceptList(&startIndex As integer, &endIndex As integer);
/* 倒序当前列表集合 */
method reverse();
/* 交换&index1和&index2的位置 */
method exchange(&index1 As integer, &index2 As integer);
/* 移除稽核内第&index个元素 */
method remove(&index As integer);
/* 移除稽核内第一个元素 */
method removeFirst();
/* 移除稽核内最后一个元素 */
method removeLast();
/* 返回集合长度 */
method getSize() Returns integer;
/* 以下为指针遍历LinkedList相关方法。
正序遍历示例:
&linkedList.initializePointerToFirst();
while &linkedList.hasNext()
&anyValue = &linkedList.next();
end-while;
倒序遍历示例:
&linkedList.initializePointerToLast();
while &linkedList.hasPrevious()
&anyValue = &linkedList.previous();
end-while;
*/
method initializePointerToFirst();
method initializePointerToLast();
/* 初始化指针到指定的&index位置上 */
method initializePointerToIndex(&index As integer);
method hasNext() Returns boolean;
method next() Returns any;
method hasPrevious() Returns boolean;
method previous() Returns any;
private
instance integer &size;
instance array &pointer;
instance array &firstNode;
instance array &lastNode;
end-class;
get len
/+ Returns Integer +/
Return %This.size;
end-get;
method add
/+ &element as Any +/
Local array &node = CreateArrayAny( Null, Null, Null);
&node [2] = &element;
%This.addNode(&node);
end-method;
method addNode
/+ &node as Array of Any +/
If %This.firstNode = Null Then
%This.firstNode = &node;
%This.lastNode = &node;
Else
%This.lastNode [3] = &node;
&node [1] = %This.lastNode;
%This.lastNode = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method addLinkedList
/+ &linkedList as GT_COMMON:UTIL:LinkedList +/
If &linkedList.len = 0 Then
Return;
Else
If %This.size = 0 Then
%This.firstNode = &linkedList.getFirstNode();
%This.lastNode = &linkedList.getLastNode();
%This.size = &linkedList.len;
Return;
End-If;
End-If;
Local array &node = &linkedList.getFirstNode();
%This.lastNode [3] = &node;
&node [1] = %This.lastNode;
%This.lastNode = &linkedList.getLastNode();
%This.size = %This.size + &linkedList.len;
end-method;
method unshift
/+ &element as Any +/
Local array &node = CreateArrayAny( Null, Null, Null);
&node [2] = &element;
%This.unshiftNode(&node);
end-method;
method unshiftNode
/+ &node as Array of Any +/
If %This.firstNode = Null Then
%This.firstNode = &node;
%This.lastNode = &node;
Else
%This.firstNode [1] = &node;
&node [1] = Null;
&node [3] = %This.firstNode;
%This.firstNode = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method unshiftLinkedList
/+ &linkedList as GT_COMMON:UTIL:LinkedList +/
If &linkedList.len = 0 Then
Return;
Else
If %This.size = 0 Then
%This.firstNode = &linkedList.getFirstNode();
%This.lastNode = &linkedList.getLastNode();
%This.size = &linkedList.len;
Return;
End-If;
End-If;
Local array &node = &linkedList.getLastNode();
%This.firstNode [1] = &node;
&node [3] = %This.firstNode;
%This.firstNode = &linkedList.getFirstNode();
%This.size = %This.size + &linkedList.len;
end-method;
method set
/+ &index as Integer, +/
/+ &element as Any +/
Local array &node = CreateArrayAny( Null, Null, Null);
&node [2] = &element;
%This.setNode(&index, &node);
end-method;
method setNode
/+ &index as Integer, +/
/+ &node as Array of Any +/
If &index = 1 Then
%This.firstNode [1] = &node;
&node [1] = Null;
&node [3] = %This.firstNode;
%This.firstNode = &node;
Else
Local array &node2 = %This.getNode(&index);
Local array &node1 = &node2 [1];
&node [1] = &node1;
&node1 [3] = &node;
&node [3] = &node2;
&node2 [1] = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method setLinkedList
/+ &index as Integer, +/
/+ &linkedList as GT_COMMON:UTIL:LinkedList +/
If &linkedList.len = 0 Then
Return;
End-If;
If &index = 1 Then
Local array &node = &linkedList.getLastNode();
%This.firstNode [1] = &node;
&node [3] = %This.firstNode;
%This.firstNode = &linkedList.getFirstNode();
Else
Local array &node2 = %This.getNode(&index);
Local array &node1 = &node2 [1];
Local array &nodeSet1 = &linkedList.getFirstNode();
Local array &nodeSet2 = &linkedList.getLastNode();
&nodeSet1 [1] = &node1;
&node1 [3] = &nodeSet1;
&nodeSet2 [3] = &node2;
&node2 [1] = &nodeSet2;
End-If;
%This.size = %This.size + &linkedList.len;
end-method;
method get
/+ &index as Integer +/
/+ Returns Any +/
Return %This.getNode(&index)[2];
end-method;
method getNode
/+ &index as Integer +/
/+ Returns Array of Any +/
If &index > %This.size Then
throw CreateException(0, 0, "数组越界:&index-" | &index | "不在集合1到" | %This.size | "范围内");
End-If;
Local array &node;
Local integer &i;
If (%This.size - &index) < &index Then /* &index靠后,从末尾开始查找 */
&node = %This.lastNode;
For &i = %This.size To 1 Step - 1
If &index = &i Then
Return &node;
End-If;
&node = &node [1];
End-For;
Else /* &index靠前,从头部开始查找 */
&node = %This.firstNode;
For &i = 1 To %This.size
If &index = &i Then
Return &node;
End-If;
&node = &node [3];
End-For;
End-If;
end-method;
method getFirst
/+ Returns Any +/
Return %This.firstNode [2];
end-method;
method getFirstNode
/+ Returns Array of Any +/
Return %This.firstNode;
end-method;
method getLast
/+ Returns Any +/
Return %This.lastNode [2];
end-method;
method getLastNode
/+ Returns Array of Any +/
Return %This.lastNode;
end-method;
method replace
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &element as Any +/
Local array &node = CreateArrayAny( Null, Null, Null);
&node [2] = &element;
%This.replaceNode(&startIndex, &endIndex, &node);
end-method;
method replaceNode
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &node as Array of Any +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local array &node2 = %This.get(&endIndex)[3];
Local array &node1 = %This.get(&startIndex)[1];
If &node2 = Null Then
%This.lastNode = &node;
Else
&node2 [1] = &node;
End-If;
&node [3] = &node2;
&node [1] = &node1;
If &node1 = Null Then
%This.firstNode = &node;
Else
&node1 [3] = &node;
End-If;
%This.size = %This.size + &endIndex - &startIndex + 2;
end-method;
method replaceToLinkedList
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &linkedList as GT_COMMON:UTIL:LinkedList +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local array &node2 = %This.get(&endIndex)[3];
Local array &node1 = %This.get(&startIndex)[1];
Local array &nodeR2 = &linkedList.getLastNode();
Local array &nodeR1 = &linkedList.getFirstNode();
If &node2 = Null Then
%This.lastNode = &nodeR2;
Else
&node2 [1] = &nodeR2;
End-If;
&nodeR2 [3] = &node2;
&nodeR1 [1] = &node1;
If &node1 = Null Then
%This.firstNode = &nodeR1;
Else
&node1 [3] = &nodeR1;
End-If;
%This.size = %This.size + &endIndex - &startIndex + 1 + &linkedList.len;
end-method;
method interceptList
/+ &startIndex as Integer, +/
/+ &endIndex as Integer +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local array &node1 = %This.get(&startIndex);
Local array &node2 = %This.get(&endIndex);
%This.firstNode = &node1;
%This.lastNode = &node2;
%This.firstNode [1] = Null;
%This.lastNode [3] = Null;
%This.size = &endIndex - &startIndex + 1;
end-method;
method reverse
/* Local array &node1 = %This.firstNode;
%This.firstNode = %This.lastNode;
%This.lastNode = &node1;
Local integer &i;
Local array &node2 = &node1[3];
Local array &node3;
For &i = 1 To %This.size
If &node2 = Null Then
Break;
End-If;
&node3 = &node2[3];
&node2[3] = &node1;
&node1[1] = &node2;
&node1 = &node2;
&node2 = &node3;
End-For;
%This.firstNode[1] = Null;
%This.lastNode[3] = Null; */
Local array &nodeLeft = %This.firstNode;
Local array &nodeRight = %This.lastNode;
Local integer &i = 1;
Local any &any;
While True
If &i * 2 > %This.size Then
Return;
End-If;
&any = &nodeLeft [2];
&nodeLeft [2] = &nodeRight [2];
&nodeRight [2] = &any;
&nodeLeft = &nodeLeft [3];
&nodeRight = &nodeRight [1];
&i = &i + 1;
End-While;
end-method;
method exchange
/+ &index1 as Integer, +/
/+ &index2 as Integer +/
Local array &node1 = %This.get(&index1);
Local array &node2 = %This.get(&index2);
Local any &any = &node1 [2];
&node1 [2] = &node2 [2];
&node2 [2] = &any;
end-method;
method remove
/+ &index as Integer +/
If &index = 1 Then
%This.removeFirst();
Return;
Else
If &index = %This.size Then
%This.removeLast();
Return;
End-If;
End-If;
Local array &node = %This.get(&index);
&node [1][3] = &node [3];
&node [3][1] = &node [1];
%This.size = %This.size - 1;
end-method;
method removeFirst
If %This.size < 2 Then
%This.firstNode = Null;
%This.lastNode = Null;
%This.size = 0;
Else
%This.firstNode = %This.firstNode [3];
%This.firstNode [1] = Null;
%This.size = %This.size - 1;
End-If;
end-method;
method removeLast
If %This.size < 2 Then
%This.firstNode = Null;
%This.lastNode = Null;
%This.size = 0;
Else
%This.lastNode = %This.lastNode [1];
%This.lastNode [3] = Null;
%This.size = %This.size - 1;
End-If;
end-method;
method getSize
/+ Returns Integer +/
Return %This.size;
end-method;
method initializePointerToFirst
%This.pointer = %This.firstNode;
end-method;
method initializePointerToLast
%This.pointer = %This.lastNode;
end-method;
method initializePointerToIndex
/+ &index as Integer +/
%This.pointer = %This.getNode(&index);
end-method;
method hasNext
/+ Returns Boolean +/
Return (%This.pointer <> Null);
end-method;
method next
/+ Returns Any +/
Local array &nd = %This.pointer;
%This.pointer = %This.pointer [3];
Return &nd [2];
end-method;
method hasPrevious
/+ Returns Boolean +/
Return (%This.pointer <> Null);
end-method;
method previous
/+ Returns Any +/
Local array &nd = %This.pointer;
%This.pointer = %This.pointer [1];
Return &nd [2];
end-method;
以下是向第一位插入2万个元素测试,对比Array:
向最后一位插入2万个元素对比:
以下是旧实现代码,节点使用实体类实现,更便于理解。仅用于示例,代码不再更新。
LinkedList类:
/* CSQ ADD 链表集合类
基于链表实现的列表集合
在执行向头部插入(unshift)或删除(removeFirst)和两个集合合并(addLinkedList)或插入(setLinkedList)时速度远远高于Array
在执行截取(interceptList)时速度远高于Array
在执行随机插入(set)和替换(replace)时整体速度高于Array
在执行末尾部插入或删除时速度与Array基本相同
执行倒序(Reverse)时速度稍低于Array
随机取数和使用for遍历时速度远低于Array,遍历时应使用迭代遍历或指针遍历方式
*/
import COMMON:util:entity:LinkedNode;
class LinkedList
/* 集合长度 */
property integer len get;
/* 添加元素到集合末尾 */
method add(&element As any);
/* 添加节点到集合末尾。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method addNode(&node As COMMON:util:entity:LinkedNode);
/* 添加集合到集合末尾。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method addLinkedList(&linkedList As COMMON:util:LinkedList);
/* 添加元素到集合前面 */
method unshift(&element As any);
/* 添加节点到集合前面。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method unshiftNode(&node As COMMON:util:entity:LinkedNode);
/* 添加集合到集合前面。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method unshiftLinkedList(&linkedList As COMMON:util:LinkedList);
/* 插入元素到集合&index位置 */
method set(&index As integer, &element As any);
/* 插入节点到集合&index位置。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method setNode(&index As integer, &node As COMMON:util:entity:LinkedNode);
/* 插入集合到集合&index位置。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method setLinkedList(&index As integer, &linkedList As COMMON:util:LinkedList);
/* 获取集合内第&index个元素 */
method get(&index As integer) Returns any;
/* 获取集合内第&index个节点 */
method getNode(&index As integer) Returns COMMON:util:entity:LinkedNode;
/* 获取集合内第一个元素 */
method getFirst() Returns any;
/* 获取集合内第一个节点 */
method getFirstNode() Returns COMMON:util:entity:LinkedNode;
/* 获取集合内最后一个元素 */
method getLast() Returns any;
/* 获取集合内最后一个节点 */
method getLastNode() Returns COMMON:util:entity:LinkedNode;
/* 替换&startIndex到&endIndex元素为&element */
method replace(&startIndex As integer, &endIndex As integer, &element As any);
/* 替换&startIndex到&endIndex节点为&element。注意:此方法会改变&node的前后指针,导致原本引用此节点的LinkedList实例的结构失效! */
method replaceNode(&startIndex As integer, &endIndex As integer, &node As COMMON:util:entity:LinkedNode);
/* 替换&startIndex到&endIndex节点为&linkedList。注意:此方法会改变&linkedList的指针数据,导致传入的&linkedList不可用! */
method replaceToLinkedList(&startIndex As integer, &endIndex As integer, &linkedList As COMMON:util:LinkedList);
/* 截取列表,保留从&startIndex到&endIndex的元素 */
method interceptList(&startIndex As integer, &endIndex As integer);
/* 倒序当前列表集合 */
method reverse();
/* 交换&index1和&index2的位置 */
method exchange(&index1 As integer, &index2 As integer);
/* 移除稽核内第&index个元素 */
method remove(&index As integer);
/* 移除稽核内第一个元素 */
method removeFirst();
/* 移除稽核内最后一个元素 */
method removeLast();
/* 返回集合长度 */
method getSize() Returns integer;
/* 以下为指针遍历LinkedList相关方法。
正序遍历示例:
&linkedList.initializePointerToFirst();
while &linkedList.hasNext()
&anyValue = &linkedList.next();
end-while;
倒序遍历示例:
&linkedList.initializePointerToLast();
while &linkedList.hasPrevious()
&anyValue = &linkedList.previous();
end-while;
*/
method initializePointerToFirst();
method initializePointerToLast();
/* 初始化指针到指定的&index位置上 */
method initializePointerToIndex(&index As integer);
method hasNext() Returns boolean;
method next() Returns any;
method hasPrevious() Returns boolean;
method previous() Returns any;
private
instance integer &size;
instance COMMON:util:entity:LinkedNode &pointer;
instance COMMON:util:entity:LinkedNode &firstNode;
instance COMMON:util:entity:LinkedNode &lastNode;
end-class;
get len
/+ Returns Integer +/
Return %This.size;
end-get;
method add
/+ &element as Any +/
Local COMMON:util:entity:LinkedNode &node = create COMMON:util:entity:LinkedNode(&element);
%This.addNode(&node);
end-method;
method addNode
/+ &node as COMMON:util:entity:LinkedNode +/
If %This.firstNode = Null Then
%This.firstNode = &node;
%This.lastNode = &node;
Else
%This.lastNode.nextNode = &node;
&node.previousNode = %This.lastNode;
%This.lastNode = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method addLinkedList
/+ &linkedList as COMMON:util:LinkedList +/
If &linkedList.len = 0 Then
Return;
Else
If %This.size = 0 Then
%This.firstNode = &linkedList.getFirstNode();
%This.lastNode = &linkedList.getLastNode();
%This.size = &linkedList.len;
Return;
End-If;
End-If;
Local COMMON:util:entity:LinkedNode &node = &linkedList.getFirstNode();
%This.lastNode.nextNode = &node;
&node.previousNode = %This.lastNode;
%This.lastNode = &linkedList.getLastNode();
%This.size = %This.size + &linkedList.len;
end-method;
method unshift
/+ &element as Any +/
Local COMMON:util:entity:LinkedNode &node = create COMMON:util:entity:LinkedNode(&element);
%This.unshiftNode(&node);
end-method;
method unshiftNode
/+ &node as COMMON:util:entity:LinkedNode +/
If %This.firstNode = Null Then
%This.firstNode = &node;
%This.lastNode = &node;
Else
%This.firstNode.previousNode = &node;
&node.previousNode = Null;
&node.nextNode = %This.firstNode;
%This.firstNode = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method unshiftLinkedList
/+ &linkedList as COMMON:util:LinkedList +/
If &linkedList.len = 0 Then
Return;
Else
If %This.size = 0 Then
%This.firstNode = &linkedList.getFirstNode();
%This.lastNode = &linkedList.getLastNode();
%This.size = &linkedList.len;
Return;
End-If;
End-If;
Local COMMON:util:entity:LinkedNode &node = &linkedList.getLastNode();
%This.firstNode.previousNode = &node;
&node.nextNode = %This.firstNode;
%This.firstNode = &linkedList.getFirstNode();
%This.size = %This.size + &linkedList.len;
end-method;
method set
/+ &index as Integer, +/
/+ &element as Any +/
Local COMMON:util:entity:LinkedNode &node = create COMMON:util:entity:LinkedNode(&element);
%This.setNode(&index, &node);
end-method;
method setNode
/+ &index as Integer, +/
/+ &node as COMMON:util:entity:LinkedNode +/
If &index = 1 Then
%This.firstNode.previousNode = &node;
&node.previousNode = Null;
&node.nextNode = %This.firstNode;
%This.firstNode = &node;
Else
Local COMMON:util:entity:LinkedNode &node2 = %This.getNode(&index);
Local COMMON:util:entity:LinkedNode &node1 = &node2.previousNode;
&node.previousNode = &node1;
&node1.nextNode = &node;
&node.nextNode = &node2;
&node2.previousNode = &node;
End-If;
%This.size = %This.size + 1;
end-method;
method setLinkedList
/+ &index as Integer, +/
/+ &linkedList as COMMON:util:LinkedList +/
If &linkedList.len = 0 Then
Return;
End-If;
If &index = 1 Then
Local COMMON:util:entity:LinkedNode &node = &linkedList.getLastNode();
%This.firstNode.previousNode = &node;
&node.nextNode = %This.firstNode;
%This.firstNode = &linkedList.getFirstNode();
Else
Local COMMON:util:entity:LinkedNode &node2 = %This.getNode(&index);
Local COMMON:util:entity:LinkedNode &node1 = &node2.previousNode;
Local COMMON:util:entity:LinkedNode &nodeSet1 = &linkedList.getFirstNode();
Local COMMON:util:entity:LinkedNode &nodeSet2 = &linkedList.getLastNode();
&nodeSet1.previousNode = &node1;
&node1.nextNode = &nodeSet1;
&nodeSet2.nextNode = &node2;
&node2.previousNode = &nodeSet2;
End-If;
%This.size = %This.size + &linkedList.len;
end-method;
method get
/+ &index as Integer +/
/+ Returns Any +/
Return %This.getNode(&index).anyProperty;
end-method;
method getNode
/+ &index as Integer +/
/+ Returns COMMON:util:entity:LinkedNode +/
If &index > %This.size Then
throw CreateException(0, 0, "数组越界:&index-" | &index | "不在集合1到" | %This.size | "范围内");
End-If;
Local COMMON:util:entity:LinkedNode &node;
Local integer &i;
If (%This.size - &index) < &index Then /* &index靠后,从末尾开始查找 */
&node = %This.lastNode;
For &i = %This.size To 1 Step - 1
If &index = &i Then
Return &node;
End-If;
&node = &node.previousNode;
End-For;
Else /* &index靠前,从头部开始查找 */
&node = %This.firstNode;
For &i = 1 To %This.size
If &index = &i Then
Return &node;
End-If;
&node = &node.nextNode;
End-For;
End-If;
end-method;
method getFirst
/+ Returns Any +/
Return %This.firstNode.anyProperty;
end-method;
method getFirstNode
/+ Returns COMMON:util:entity:LinkedNode +/
Return %This.firstNode;
end-method;
method getLast
/+ Returns Any +/
Return %This.lastNode.anyProperty;
end-method;
method getLastNode
/+ Returns COMMON:util:entity:LinkedNode +/
Return %This.lastNode;
end-method;
method replace
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &element as Any +/
Local COMMON:util:entity:LinkedNode &node = create COMMON:util:entity:LinkedNode(&element);
%This.replaceNode(&startIndex, &endIndex, &node);
end-method;
method replaceNode
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &node as COMMON:util:entity:LinkedNode +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local COMMON:util:entity:LinkedNode &node2 = %This.get(&endIndex).nextNode;
Local COMMON:util:entity:LinkedNode &node1 = %This.get(&startIndex).previousNode;
If &node2 = Null Then
%This.lastNode = &node;
Else
&node2.previousNode = &node;
End-If;
&node.nextNode = &node2;
&node.previousNode = &node1;
If &node1 = Null Then
%This.firstNode = &node;
Else
&node1.nextNode = &node;
End-If;
%This.size = %This.size + &endIndex - &startIndex + 2;
end-method;
method replaceToLinkedList
/+ &startIndex as Integer, +/
/+ &endIndex as Integer, +/
/+ &linkedList as COMMON:util:LinkedList +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local COMMON:util:entity:LinkedNode &node2 = %This.get(&endIndex).nextNode;
Local COMMON:util:entity:LinkedNode &node1 = %This.get(&startIndex).previousNode;
Local COMMON:util:entity:LinkedNode &nodeR2 = &linkedList.getLastNode();
Local COMMON:util:entity:LinkedNode &nodeR1 = &linkedList.getFirstNode();
If &node2 = Null Then
%This.lastNode = &nodeR2;
Else
&node2.previousNode = &nodeR2;
End-If;
&nodeR2.nextNode = &node2;
&nodeR1.previousNode = &node1;
If &node1 = Null Then
%This.firstNode = &nodeR1;
Else
&node1.nextNode = &nodeR1;
End-If;
%This.size = %This.size + &endIndex - &startIndex + 1 + &linkedList.len;
end-method;
method interceptList
/+ &startIndex as Integer, +/
/+ &endIndex as Integer +/
If &startIndex > &endIndex Then
Local integer &i = &startIndex;
&startIndex = &endIndex;
&endIndex = &i;
End-If;
Local COMMON:util:entity:LinkedNode &node1 = %This.get(&startIndex);
Local COMMON:util:entity:LinkedNode &node2 = %This.get(&endIndex);
%This.firstNode = &node1;
%This.lastNode = &node2;
%This.firstNode.previousNode = Null;
%This.lastNode.nextNode = Null;
%This.size = &endIndex - &startIndex + 1;
end-method;
method reverse
/* Local COMMON:util:entity:LinkedNode &node1 = %This.firstNode;
%This.firstNode = %This.lastNode;
%This.lastNode = &node1;
Local integer &i;
Local COMMON:util:entity:LinkedNode &node2 = &node1.nextNode;
Local COMMON:util:entity:LinkedNode &node3;
For &i = 1 To %This.size
If &node2 = Null Then
Break;
End-If;
&node3 = &node2.nextNode;
&node2.nextNode = &node1;
&node1.previousNode = &node2;
&node1 = &node2;
&node2 = &node3;
End-For;
%This.firstNode.previousNode = Null;
%This.lastNode.nextNode = Null; */
Local COMMON:util:entity:LinkedNode &nodeLeft = %This.firstNode;
Local COMMON:util:entity:LinkedNode &nodeRight = %This.lastNode;
Local integer &i = 1;
Local any &any;
While True
If &i * 2 > %This.size Then
Return;
End-If;
&any = &nodeLeft.anyProperty;
&nodeLeft.anyProperty = &nodeRight.anyProperty;
&nodeRight.anyProperty = &any;
&nodeLeft = &nodeLeft.nextNode;
&nodeRight = &nodeRight.previousNode;
&i = &i + 1;
End-While;
end-method;
method exchange
/+ &index1 as Integer, +/
/+ &index2 as Integer +/
Local COMMON:util:entity:LinkedNode &node1 = %This.get(&index1);
Local COMMON:util:entity:LinkedNode &node2 = %This.get(&index2);
Local any &any = &node1.anyProperty;
&node1.anyProperty = &node2.anyProperty;
&node2.anyProperty = &any;
end-method;
method remove
/+ &index as Integer +/
If &index = 1 Then
%This.removeFirst();
Return;
Else
If &index = %This.size Then
%This.removeLast();
Return;
End-If;
End-If;
Local COMMON:util:entity:LinkedNode &node = %This.get(&index);
&node.previousNode.nextNode = &node.nextNode;
&node.nextNode.previousNode = &node.previousNode;
%This.size = %This.size - 1;
end-method;
method removeFirst
If %This.size < 2 Then
%This.firstNode = Null;
%This.lastNode = Null;
%This.size = 0;
Else
%This.firstNode = %This.firstNode.nextNode;
%This.firstNode.previousNode = Null;
%This.size = %This.size - 1;
End-If;
end-method;
method removeLast
If %This.size < 2 Then
%This.firstNode = Null;
%This.lastNode = Null;
%This.size = 0;
Else
%This.lastNode = %This.lastNode.previousNode;
%This.lastNode.nextNode = Null;
%This.size = %This.size - 1;
End-If;
end-method;
method getSize
/+ Returns Integer +/
Return %This.size;
end-method;
method initializePointerToFirst
%This.pointer = %This.firstNode;
end-method;
method initializePointerToLast
%This.pointer = %This.lastNode;
end-method;
method initializePointerToIndex
/+ &index as Integer +/
%This.pointer = %This.getNode(&index);
end-method;
method hasNext
/+ Returns Boolean +/
Return (%This.pointer <> Null);
end-method;
method next
/+ Returns COMMON:util:entity:LinkedNode +/
Local COMMON:util:entity:LinkedNode &nd = %This.pointer;
%This.pointer = %This.pointer.nextNode;
Return &nd.anyProperty ;
end-method;
method hasPrevious
/+ Returns Boolean +/
Return (%This.pointer <> Null);
end-method;
method previous
/+ Returns COMMON:util:entity:LinkedNode +/
Local COMMON:util:entity:LinkedNode &nd = %This.pointer;
%This.pointer = %This.pointer.previousNode;
Return &nd.anyProperty ;
end-method;
LinkedNode类:
/* 此类是一个链表集合节点实体类 */
class LinkedNode
/* 上一个节点 */
property GT_COMMON:UTIL:entity:LinkedNode previousNode;
/* 下一个节点 */
property GT_COMMON:UTIL:entity:LinkedNode nextNode;
/* 存放节点信息 */
property any anyProperty;
method LinkedNode(&property As any);
end-class;
method LinkedNode
/+ &property as Any +/
%This.anyProperty = &property;
end-method;