更新删除后的链表索引

huangapple go评论106阅读模式
英文:

Updating LinkList index's after remove

问题

我在练习使用链表,并尝试从头开始创建一个移除节点的方法,该方法能够移除链表中的节点并更新我为每个节点关联的索引值。我已经尝试了一些逻辑来处理不同情况,但它们似乎都不正确。每种情况下的节点索引更新也似乎不正确。

链表类的实例变量:

  1. public class LinkedList<E> implements DynamicList<E> {
  2. LLNode<E> head;
  3. LLNode<E> tail;
  4. int llSize;
  5. LinkedList(){
  6. this.head = null;
  7. this.tail = null;
  8. this.llSize = 0;
  9. }
  10. }

节点类:

  1. public class LLNode<E> {
  2. E obj;
  3. LLNode<E> previousPointer;
  4. LLNode<E> nextPointer;
  5. int index;
  6. public LLNode(E obj){
  7. this.obj = obj;
  8. this.index = 0;
  9. }
  10. // 省略了其他方法和getter/setter
  11. }

移除方法:

  1. @Override
  2. public E remove(E data) {
  3. LLNode<E> nodeToRemove = new LLNode<>(data);
  4. if(head == null){
  5. return null;
  6. }
  7. if(head.getObj().equals(nodeToRemove.getObj())){
  8. head = nodeToRemove.nextPointer;
  9. // 不确定这段代码是否有效....
  10. LLNode<E> currentNode = this.head;
  11. for(int i = 0; i < size() - 2; i++){
  12. currentNode.setIndex(i);
  13. currentNode = currentNode.nextPointer;
  14. }
  15. return nodeToRemove.getObj();
  16. }
  17. if(nodeToRemove.nextPointer != null){
  18. nodeToRemove.nextPointer.previousPointer = nodeToRemove.previousPointer;
  19. LLNode<E> currentNode = nodeToRemove;
  20. int startIndex = size() - countFrom(nodeToRemove);
  21. for(int i = 0; i < countFrom(nodeToRemove); i++){
  22. currentNode.setIndex(startIndex);
  23. startIndex++;
  24. currentNode = currentNode.nextPointer;
  25. }
  26. return nodeToRemove.getObj();
  27. }
  28. if(nodeToRemove.previousPointer != null){
  29. nodeToRemove.previousPointer.nextPointer = nodeToRemove.nextPointer;
  30. LLNode<E> currentNode = nodeToRemove;
  31. int startIndex = size() - countFrom(nodeToRemove);
  32. for(int i = 0; i < countFrom(nodeToRemove); i++){
  33. currentNode.setIndex(startIndex);
  34. startIndex++;
  35. currentNode = currentNode.nextPointer;
  36. }
  37. return nodeToRemove.getObj();
  38. }
  39. this.llSize--;
  40. return null;
  41. }

countFrom方法:

  1. private int countFrom(LLNode<E> startNode){
  2. int count = 0;
  3. while(startNode != null){
  4. startNode = startNode.nextPointer;
  5. count++;
  6. }
  7. return count;
  8. }

如果需要更多的代码,请告诉我。

英文:

I'm practicing with LinkLists and trying to make a remove method from scratch that removes the node in the linked list and also updates index values that I have associated with each node. I have tried some logic for different cases but they don't seem right. The node index updating for each case doesn't seem right either.

LinkedList Class instance variables

  1. public class LinkedList&lt;E&gt; implements DynamicList&lt;E&gt; {
  2. LLNode&lt;E&gt; head;
  3. LLNode&lt;E&gt; tail;
  4. int llSize;
  5. LinkedList(){
  6. this.head = null;
  7. this.tail = null;
  8. this.llSize =0;
  9. }

Node class

  1. public class LLNode&lt;E&gt;{
  2. E obj;
  3. LLNode&lt;E&gt; previousPointer;
  4. LLNode&lt;E&gt; nextPointer;
  5. int index;
  6. public LLNode(E obj){
  7. this.obj = obj;
  8. this.index=0;
  9. }
  10. public E getObj() {
  11. return obj;
  12. }
  13. public LLNode&lt;E&gt; getPreviousPointer() {
  14. return previousPointer;
  15. }
  16. public LLNode&lt;E&gt; getNextPointer() {
  17. return nextPointer;
  18. }
  19. public int getIndex() {
  20. return index;
  21. }
  22. public void setIndex(int index) {
  23. this.index = index;
  24. }
  25. }

remove method

  1. @Override
  2. public E remove(E data) {
  3. LLNode&lt;E&gt; nodeToRemove = new LLNode&lt;&gt;(data);
  4. if(head == null){
  5. return null;
  6. }
  7. if(head.getObj().equals(nodeToRemove.getObj())){
  8. head = nodeToRemove.nextPointer;
  9. //not sure if this works....
  10. LLNode&lt;E&gt; currentNode = this.head;
  11. for(int i=0; i &lt; size()-2; i++){
  12. currentNode.setIndex(i);
  13. currentNode = currentNode.nextPointer;
  14. }
  15. return nodeToRemove.getObj();
  16. }
  17. //this is not right
  18. if(nodeToRemove.nextPointer != null){
  19. nodeToRemove.nextPointer.previousPointer = nodeToRemove.previousPointer;
  20. // do I have to update the nodeToRemove&#39;s previous to point to its new next?
  21. LLNode&lt;E&gt; currentNode = nodeToRemove;
  22. int startIndex = size()- countFrom(nodeToRemove);
  23. for(int i = 0; i &lt; countFrom(nodeToRemove); i++){
  24. currentNode.setIndex(startIndex);
  25. startIndex++;
  26. currentNode = currentNode.nextPointer;
  27. }
  28. return nodeToRemove.getObj();
  29. }
  30. if(nodeToRemove.previousPointer != null){
  31. nodeToRemove.previousPointer.nextPointer = nodeToRemove.nextPointer;
  32. //node index updating
  33. LLNode&lt;E&gt; currentNode = nodeToRemove;
  34. int startIndex = size()- countFrom(nodeToRemove);
  35. for(int i = 0; i &lt; countFrom(nodeToRemove); i++){
  36. currentNode.setIndex(startIndex);
  37. startIndex++;
  38. currentNode = currentNode.nextPointer;
  39. }
  40. return nodeToRemove.getObj();
  41. }
  42. this.llSize--;
  43. return null;
  44. }

countFrom method

  1. private int countFrom(LLNode&lt;E&gt; startNode){
  2. int count=0;
  3. while(startNode != null){
  4. startNode = startNode.nextPointer;
  5. count++;
  6. }
  7. return count;
  8. }

Let me know if more code is needed.

答案1

得分: 0

你只需要重新编号在移除节点之后的节点。

所以:

  1. public E remove(E data) {
  2. LLNode<E> nodeToRemove = new LLNode<>();
  3. if (head == null) {
  4. return null;
  5. }
  6. // 在必要时调整头部和尾部
  7. if (tail.getObj().equals(nodeToRemove.getObj())) {
  8. tail = nodeToRemove.previousPointer;
  9. }
  10. if (head.getObj().equals(nodeToRemove.getObj())) {
  11. head = nodeToRemove.nextPointer;
  12. }
  13. // 重连链表跳过要移除的节点
  14. if (nodeToRemove.nextPointer != null) {
  15. nodeToRemove.nextPointer.previousPointer = nodeToRemove.previousPointer;
  16. }
  17. if (nodeToRemove.previousPointer != null) {
  18. nodeToRemove.previousPointer.nextPointer = nodeToRemove.nextPointer;
  19. }
  20. // 重新编号在移除节点之后的节点
  21. // 之前的节点保留其索引
  22. LLNode<E> currentNode = nodeToRemove.nextPointer;
  23. int index = nodeToRemove.getIndex();
  24. while (currentNode != null) {
  25. currentNode.setIndex(index);
  26. index++;
  27. currentNode = currentNode.nextPointer;
  28. }
  29. this.llSize--;
  30. return nodeToRemove.getObj();
  31. }
英文:

You should only need to renumber the nodes that follow after the removed node.

So:

  1. public E remove(E data) {
  2. LLNode&lt;E&gt; nodeToRemove = new LLNode&lt;&gt;(data);
  3. if(head == null){
  4. return null;
  5. }
  6. // Adapt head and tail when necessary
  7. if(tail.getObj().equals(nodeToRemove.getObj())){
  8. tail = nodeToRemove.previousPointer;
  9. }
  10. if(head.getObj().equals(nodeToRemove.getObj())){
  11. head = nodeToRemove.nextPointer;
  12. }
  13. // Rewire the list so it skips the node to remove
  14. if(nodeToRemove.nextPointer != null){
  15. nodeToRemove.nextPointer.previousPointer = nodeToRemove.previousPointer;
  16. }
  17. if(nodeToRemove.previousPointer != null){
  18. nodeToRemove.previousPointer.nextPointer = nodeToRemove.nextPointer;
  19. }
  20. // Renumber the nodes that follow the removed node.
  21. // (Those before it retain their index)
  22. LLNode&lt;E&gt; currentNode = nodeToRemove.nextPointer;
  23. int index = nodeToRemove.getIndex();
  24. while (currentNode != null) {
  25. currentNode.setIndex(index);
  26. index++;
  27. currentNode = currentNode.nextPointer;
  28. }
  29. this.llSize--;
  30. return nodeToRemove.getObj();
  31. }

答案2

得分: 0

  1. 我已经解决了这个问题现在看起来运行良好以下是我的更改
  2. get() 方法
  3. 我添加了一个计数变量用于与传入的参数进行比较同时我的 while 循环比较部分之前是检查 current.next 而不是 current因此出现了空指针
  4. ```java
  5. public E get(int index) {
  6. LLNode<E> current = this.head;
  7. int count = 0;
  8. while (current != null) {
  9. if (index == count) {
  10. return current.getObj();
  11. }
  12. current = current.nextPointer;
  13. count++;
  14. }
  15. return null;
  16. }

remove() 方法

我使用了 while 循环替代了之前的逻辑,并且大大简化了逻辑。

  1. @Override
  2. public E remove(E data) {
  3. LLNode<E> current = this.head;
  4. while (current != null) {
  5. if (current.getObj().equals(data)) {
  6. LLNode<E> prev = current.previousPointer;
  7. LLNode<E> next = current.nextPointer;
  8. if (prev != null) {
  9. prev.nextPointer = next;
  10. }
  11. if (next != null) {
  12. next.previousPointer = prev;
  13. }
  14. llSize--;
  15. return current.getObj();
  16. }
  17. current = current.nextPointer;
  18. }
  19. return null;
  20. }
  1. <details>
  2. <summary>英文:</summary>
  3. I figured it out and this seems to be working well now, here are my changes.
  4. get() Method
  5. Added a count variable to compare with the passed parameter also my while comparison was checking current.next and not current and was getting null pointer.

public E get(int index) {
LLNode<E> current = this.head;
int count = 0;

  1. while(current != null){
  2. if(index == count) {
  3. return current.getObj();
  4. }
  5. current = current.nextPointer;
  6. count++;
  7. }
  8. return null;
  9. }
  1. remove() Method
  2. I used a while instead of the previous logic. and simplified the logic quite a bit.

@Override
public E remove(E data) {
LLNode<E> current = this.head;
while(current != null){
if(current.getObj().equals(data)) {

  1. LLNode&lt;E&gt; prev = current.previousPointer;
  2. LLNode&lt;E&gt; next = current.nextPointer;
  3. if(prev != null) {
  4. prev.nextPointer = next;
  5. }
  6. if(next != null) {
  7. next.previousPointer = prev;
  8. }
  9. llSize--;
  10. return current.getObj();
  11. }
  12. current = current.nextPointer;
  13. }
  14. return null;
  15. }
  1. </details>

huangapple
  • 本文由 发表于 2020年10月21日 04:05:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/64452585.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定