双方向循環リストとは何ですか
リストには、明確なアイデアを持っていない場合は、双方向循環リンクリストを見る前に、私はあなたが見てお勧め単一のリストと片方向循環リンクリストあなたの以下のよりよい理解を助長しています、。(ナンセンスより少し[エスケープします]
単独でリンクされたリストを比較して、双方向円形のリンクリストは、より複雑な構造です。ノードの唯一の方法は、円形のリンクリストは、ポインタが含まれているため(次の)さらに前方ノードへのポインタ(PREV)点を含む、次のノードを指します。
- 双方向循環リスト、最初のポインタは、可視ヘッド、ならびに尾ノードの終わりではありません。これは、リストと単一の差です。
- 双方向円形のリンクリストノードポインティング端のヘッドのヘッドポインタ、ノードポインティングヘッドのテールエンドノードの前に。
基本操作
基本的な操作方法は、円形のリンクリストです:増加(追加)、削除(削除)、変更(設定)、チェック(見つける)、挿入(挿入)などが挙げられます。ここでは唯一、削除挿入しgetNode動作を説明する、他の実装は、以下のソースを見ることができます。
ノードを取得します。
可視ノード(ヘッドおよび端)の双方向リンクリスト、こうして得双方向円形のリンクリスト単一リンクリストノード動作は異なり。
- ノード番号リストの長さを取得する必要がある/ 2比較
- もし、ノードが前に記載されており、次のダウンしたがって、ヘッドからのすべての方法に付勢されている未満
- それは超えている場合、ノードが部分的説明であり、したがって、すべての方法アップ終了前から
- この設計は、動作時間の複雑さを可能にgetNode短縮O(logN個)
要素を削除します
- 削除対象のノードのノード要素を取得します
- ノードは、ノードのノードである前に次のポインタは、ノードが提供されます。node.prev.next = node.next:として具現
- ノードポインタPREV、ノードは、ノードのフロントノードに設定されています。node.next.prev = node.prev:として具現
- ノードへのポインタが存在しないので、ノードは自動的にクリーンアップになり
- 可変長レコードリスト-1
要素を挿入
- ノードnode要素が挿入されるように取得します
- node.prevにノードMYNODE、次の点ノード、前のポイントを作成します
- ノードnode.prevのMYNODE隣点
- 前のノードの前のノードはMYNODEポインティング
賛否両論の双方向循環リスト
優位
- 単鎖、サイクルは、単一リンクリストよりも高速であるすべての基本的な操作の双方向リンクリストと比較(JavaクラスLINKLIST源は、双方向円形のリンクされたリストです)
- ノードは、ノードの正面に非常に柔軟取得することができます
恵まれません
- 単独リンクリストを比較すると、メモリ空間の二重リンクリストは明らかにはるかに大きいです
二重より多くのスペースを消費することにより、動作時間の複雑さを軽減するために設計されたアルゴリズムを考える「時間のための空間」の設計アプリケーションのリストをリンク。
ソースコードの実装
public class Node<Anytype> {
public Anytype data;//数据
public Node<Anytype> prev;//前一个节点
public Node<Anytype> next;//后一个节点
public Node(Anytype data,Node<Anytype> prev,Node<Anytype> next){
this.data=data;
this.prev=prev;
this.next=next;
}
}
----------------------------------------------
public class DoubleLink<AnyType> {
Node<AnyType> head;//头指针
Node<AnyType> end;//尾节点
int size;//记录链表长度
//初始化链表
public void initlist(){
end=new Node<>(null,null,null);
head=new Node<>(null,null,end);
end.prev=head;
end.next=head;
size=0;
}
//获取长度
public int length(){
return size;
}
//获取节点
public Node<AnyType> getNode(int index){
Node<AnyType> n;
if(index>=size/2){
n=end;
for(int i=length();i>index;i--){
n=n.prev;
}
return n;
}
else{
n=head;
for(int i=0;i<=index;i++){
n=n.next;
}
return n;
}
}
//添加元素
public void add(AnyType a){
Node<AnyType> renode=new Node<>(a,getNode(size-1),end);
renode.prev.next=renode;
renode.next.prev=renode;
size++;
}
//插入元素
public void insert(int i,AnyType a){
Node<AnyType> n=getNode(i);
Node<AnyType> renode=new Node<>(a,n.prev,n);
n.prev.next=renode;
n.prev=renode;
size++;
}
//删除元素
public AnyType remove(int i){
Node<AnyType> n=getNode(i);
AnyType data=n.data;
n.prev.next=n.next;
n.next.prev=n.prev;
size--;
return data;
}
//获取i位置的数据
public AnyType get(int i){
return getNode(i).data;
}
//为i位置元素重新赋值
public AnyType set(int i,AnyType a){
Node<AnyType> n=getNode(i);
AnyType old=n.data;
n.data=a;
return old;
}
//清空链表
public void clear(){
initlist();
}
public void print(){
for(int i=0;i<size;i++){
System.out.println(getNode(i).data);
}
}
}