私が持っている課題についての質問は、新しいリストを生成するLinkedListをθ(N)回反転するアルゴリズムを書くことです。JavaでLinkedListを反転するこのアルゴリズムがθ(N)に合わないのはなぜですか?
私が思いついたコードは、時間の要件を満たしていないため、私はその理由を理解できません。
public Node reverse() {
if (this == Node.NIL) {
return Node.NIL;
}
if (this.getNext() == Node.NIL) {
return new Node(this.getItem(), this.getNext());
}
Node curNode = new Node(this.getItem(), this.getNext());
Node front = curNode;
Node nextNode = null;
Node prevNode = null;
while (curNode.getNext() != Node.NIL) {
nextNode = new Node(curNode.next.item, curNode.next.next);
curNode.next = prevNode;
prevNode = curNode;
curNode = nextNode;
}
curNode.next = prevNode;
front.setNext(Node.NIL);
return curNode;
}
あり、常に逆転させるために用意リストに作成された最初のノードであるNode.NILと呼ばれるべきNILと呼ばれるノードがあるので、Node.NILは次のノードである場合は、になりますリストの最後。
各ノードには、「next」と「item」の2つの属性があります。「next」はリストの次のノードで、「item」は持ち歩くデータで、この場合はObjectです。
これは(NCASES = 20)が使用されている試験である:
@Test
public void testReverseTiming() {
int i;
long diff = 0;
for (i = 0; i < NCASES - 1; i++) {
long start = System.nanoTime();
Node result = nodes2[i].reverse();
long end = System.nanoTime();
diff = end - start;
if (diff/1000000 > 250) {
i++;
break;
}
}
long start = System.nanoTime();
Node result = nodes2[i].reverse();
long end = System.nanoTime();
long diff2 = end - start;
double ratio = (double) diff2/(double) diff;
assertTrue("reverse should scale linearly with list size", ratio > 1.2);
assertTrue("reverse should scale linearly with list size", ratio < 2.5);
}
それは1.2と2.5の間であることが必要であるのに対し、自分のコードは、25から35までの範囲を生成する比率。
これはO(n)のようです。光り輝く非効率なことをしない限り、私は常にO(n)になることを期待しています。 – Carcigenicate
@Carcigenicate質問の編集内容をご覧ください。 – waddington
私はあなたがテストでやっていることを実際には得られません。そして、私は 'reverse'のwhileループがリスト内の要素と同じくらい多くの回数実行されることを期待しています(アルゴリズムが正しいと仮定して、私はあまりにもそれを見て疲れています)。 (n)。複雑さを検証するために実際にアルゴリズムのタイミングを聞いたことはありません。それが正確であるためには、あまりにも多くのことが起こっている可能性があります。 – Carcigenicate