List 链表

List

List - 图1

CBrother链表是双向链表,每个元素都知道自己前面的元素与后面的元素,可以快速删除于插入,但是无法直接通过下标访问。

函数描述参数返回值用法
addFirst(obj) 添加元素到链表头 obj:要添加的元素 myList.addFirst(5)
addLast(obj) 添加元素到链表尾 obj:要添加的元素 myList.addLast(4)
size() 获取链表长度 链表元素个数 var nowsize = myList.size()
popFirst() 移除链表头元素,第二个节点设为头 被移除的元素 var delobj = myList.popFirst()
popLast() 移除链表尾元素,倒数第二节点设为尾 被移除的元素 var delobj = myList.popLast(1)
clear() 清空链表 myList.clear()
begin() 开始从头遍历链表 myList.begin()
end() 开始从尾遍历链表 myList.end()
get() 遍历中获取当前节点 当前节点 var obj = myList.get()
pop() 遍历中删除当前节点,跳入便利顺序的下一节点 被移除的元素 myList.pop()
next() 遍历中跳入后面一个节点 false:到最尾了,true:成功 myList.next()
fornt() 遍历中跳入前面一个节点 false:到头了,true:成功 myList.fornt()
insertFornt(obj) 遍历中在前面插入一个元素 obj:要添加的元素 myList.insertFornt(5)
insertNext(obj) 遍历中在后面插入一个元素 obj:要添加的元素 myList.insertNext(5)

例子:

  1. function main(parm)
  2. {
  3. var myList = new List();
  4. myList.addLast(5);
  5. myList.addLast(4);
  6. myList.addLast(3);
  7. var len = myList.size();
  8. print "myList size:" + len;
  9. var idx = 0;
  10. myList.begin();
  11. do
  12. {
  13. print "myList " + idx + ":" + myList.get();
  14. idx++;
  15. } while(myList.next());
  16. myList.addFirst(10);
  17. myList.addFirst(11);
  18. len = myList.size();
  19. print "after addFirst. myList size:" + len;
  20. idx = 0;
  21. myList.begin();
  22. do
  23. {
  24. print "myList " + idx + ":" + myList.get();
  25. idx++;
  26. } while(myList.next());
  27. myList.popFirst();
  28. myList.popLast();
  29. len = myList.size();
  30. print "after pop. myList size:" + len;
  31. idx = len - 1;
  32. myList.end(); //倒序遍历
  33. do
  34. {
  35. print "myList " + idx + ":" + myList.get();
  36. idx--;
  37. } while(myList.fornt());
  38. myList.clear();
  39. len = myList.size();
  40. print "after clear. myList size:" + len;
  41. }

结果:

  1. myList size:3
  2. myList 0:5
  3. myList 1:4
  4. myList 2:3
  5. after addFirst. myList size:5
  6. myList 0:11
  7. myList 1:10
  8. myList 2:5
  9. myList 3:4
  10. myList 4:3
  11. after pop. myList size:3
  12. myList 2:4
  13. myList 1:5
  14. myList 0:10
  15. after clear. myList size:0

例子2:

  1. function main(parm)
  2. {
  3. var myList = new List();
  4. myList.addLast(5);
  5. myList.addLast(4);
  6. myList.addLast(3);
  7. var len = myList.size();
  8. print "myList size:" + len;
  9. var idx = 0;
  10. myList.begin();
  11. do
  12. {
  13. print "myList " + idx + ":" + myList.get();
  14. idx++;
  15. } while(myList.next());
  16. myList.begin();
  17. do
  18. {
  19. var obj = myList.get();
  20. if(obj == 4)
  21. {
  22. myList.insertFornt(100); //4前面插入100 后面插入200
  23. myList.insertNext(200);
  24. break;
  25. }
  26. } while(myList.next());
  27. var len = myList.size();
  28. print "after insert.myList size:" + len;
  29. idx = 0;
  30. myList.begin();
  31. do
  32. {
  33. print "myList " + idx + ":" + myList.get();
  34. idx++;
  35. } while(myList.next());
  36. print "========================";
  37. idx = 0;
  38. myList.begin();
  39. do
  40. {
  41. var obj = myList.get();
  42. if(obj == 4)
  43. {
  44. myList.pop(); //正序遍历,自动跳入后面一个节点,所以要结束本地循环,因为继续执行myList.next()会多跳过一个节点,导致结果错误。
  45. continue;
  46. }
  47. print "myList " + idx + ":" + myList.get();
  48. idx++;
  49. } while(myList.next());
  50. len = myList.size();
  51. print "after pop. myList size:" + len;
  52. idx = len - 2; //因为下面要删除一个节点,所以多减了1,让序号打印正确
  53. myList.end();
  54. do
  55. {
  56. var obj = myList.get();
  57. if(obj == 100)
  58. {
  59. myList.pop(); //倒序遍历,自动跳入后面一个节点,所以要继续执行myList.fornt()
  60. }
  61. print "myList " + idx + ":" + myList.get();
  62. idx--;
  63. } while(myList.fornt());
  64. }

结果:

  1. myList size:3
  2. myList 0:5
  3. myList 1:4
  4. myList 2:3
  5. after insert.myList size:5
  6. myList 0:5
  7. myList 1:100
  8. myList 2:4
  9. myList 3:200
  10. myList 4:3
  11. ========================
  12. myList 0:5
  13. myList 1:100
  14. myList 2:200
  15. myList 3:3
  16. after pop. myList size:4
  17. myList 2:3
  18. myList 1:200
  19. myList 0:5

以上的遍历方法在多线程读的情况下也要加锁,比如线程1调用了next(),线程2又调用了begin(),那么线程1将获取不到自己想要的值。foreach可以解决这个问题。

foreach支持

foreach语句中的key表示当前遍历第几个元素,建议逻辑上不要依赖于这个值,value表示这个元素

  1. function main(parm)
  2. {
  3. var myList = new List();
  4. myList.addLast(5);
  5. myList.addLast(4);
  6. myList.addLast(3);
  7. foreach(k,v : myList)
  8. {
  9. print "k:" + k + ",v=" + v;
  10. }
  11. }

结果:

  1. k:0,v=5
  2. k:1,v=4
  3. k:2,v=3