我目前正试图了解ADT实现,特别是链接列表的实现(我使用Java 5来实现这一点)。
我有两个问题:
(1)我为add(i,x)写的这个实现是否正确有效?
public void add(int i, Object x) { // Possible Cases: // // 1. The list is non-empty, but the requested index is out of // range (it must be from 0 to size(), inclusive) // // 2. The list itself is empty, which will only work if i = 0 // // This implementation of add(i, x) relies on finding the node just before // the requested index i. // These will be used to traverse the list Node currentNode = head; int indexCounter = 0; // This will be used to mark the node before the requested index node int targetIndex = i - 1; // This is the new node to be inserted in the list Node newNode = new Node(x); if (currentNode != null) { while (indexCounter < targetIndex && currentNode.getNext() != null) { indexCounter++; currentNode = currentNode.getNext(); } if (indexCounter == targetIndex) { newNode.setNext(currentNode.getNext()); currentNode.setNext(newNode); } else if (i == 0) { newNode.setNext(head); head = newNode; } } else if (i == 0) { head = newNode; } }
(2)我发现这种方法很难实施。说实话,我花了好几天。这很难承认,因为我喜欢编程并且在几种语言和平台中考虑自己处于中级水平。我从13岁开始编程(苹果IIc上的Applesoft BASIC!)并拥有CS学位。我目前是一名软件测试人员,并计划在某些时候成为开发人员。所以我的问题的第二部分是:我是在欺骗自己,这是我擅长的工作类型,还是几乎每个人都发现这种问题具有挑战性?有些东西告诉我,即使是经验丰富的开发人员,面对实施这种方法,也会发现它具有挑战性。
感谢您对第二部分的反馈和建议。
答案 0 :(得分:4)
我认为这是一个好的开始......一些建议:
答案 1 :(得分:1)
我建议你先写一些单元测试。特别是,尝试在列表末尾添加一个节点,看看会发生什么。 ;)
我认为大多数开发人员会发现编写LinkedList很困难,因为a)有很多方法可以实现它,而b)它不是你通常自己写的东西。您通常会使用其中一个有效的现有实现。 ;)
作为一项练习,这是一个好主意。我建议你阅读内置LinkedList的代码,并思考如何以不同的方式做事。例如如何简化它可能是一个开始。
答案 2 :(得分:1)
此实现效率不高,但这部分是因为操作add(i,x)在普通链表上效率不高。链接列表不适用于随机访问。我想如果你创建了一个哈希表或其他东西,你可能会在列表中创建一个更有效的索引。例如,考虑Map。然后你的map.ContainsKey(i-1)map.get(i-1)的插入例程(显然有i = 0的特殊情况)你立即得到了先前的索引。如果我!= 0并且您没有该索引的密钥,那么您就会立即知道错误。如果没有太多的冲突,Map理论上是O(1),所以这比每次迭代列表更有效(但是以某些磁盘空间为代价)。这又真的取决于因为纯链表对于add(i,x)来说效率不高。
我不是特别喜欢这种方法,因为如果你说添加(32,x)并且列表中只有15个项目它会无声地失败。它应该至少抛出一个异常,返回false或某些东西,以表明插入失败。
你也可以合并两个特例。假设newNode.setNext(NULL)有效,你只需要检查i == 0,然后你可以执行newNode.setNext(head),head = newNode,因为列表是否为空,这是否有效。如果列表为空,则将下一个指针设置为NULL。这至少消除了重复的代码。
花一个星期看起来确实有点多,但是有些人在首先围绕指针(javaspeak中的类引用......)时遇到了很多麻烦。你最终得到了一些工作的事实是朝着正确方向迈出的一大步。