連結リスト
連結リストの性質
要素の追加と先頭からの要素の削除が一定時間でできます。 k番目の要素にアクセスするにはk回計算が必要になります。
単方向連結リスト
pythonでの実装です。
class Node(): def __init__(self, d): self.data = d self.next = None def appendToTail(self, d): end = Node(d) n = self while(n.next): n = n.next n.next = end def deleteNode(head, d): """ 初めに出てきたdを削除する """ n = head if(n.data == d): return head.next while(n.next): if(n.next.data == d): n.next = n.next.next return head n = n.next return head
nodeの削除を行ってみます。
if __name__ == "__main__": node = Node(10) for i in range(10): node.appendToTail(i%5) print("元の単方向連結リスト") _ = node print("%d" % _.data, end="") while(_.next): # nodeがNoneでない間回る。 _ = _.next print(" -> %d"%_.data, end="") node = deleteNode(node, 3) print("\n初めに出てくる3を削除した") _ = node print("%d" % _.data, end="") while(_.next): # nodeがNoneでない間回る。 _ = _.next print(" -> %d"%_.data, end="")
すると出力は
元の単方向連結リスト 5 -> 0 -> 1 -> 2 -> 3 -> 4 -> 0 -> 1 -> 2 -> 3 -> 4 初めに出てくる3を削除した 5 -> 0 -> 1 -> 2 -> 4 -> 0 -> 1 -> 2 -> 3 -> 4
双方向連結リスト
pythonで実装しました。
前と次が参照できます。
# 双方向連結リスト class LinkedList(): def __init__(self, d, n=None, p=None): self.data = d self.prev = None self.next = None self.setNext(n) self.setPrevious(p) def setNext(self, n): self.next = n if(n != None) and (n.prev != self): n.setPrevious(self) def setPrevious(self, p): self.prev = p if(p != None) and (p.next != self): p.setNext(self)
実際に連結リストを作成してみます。
if __name__ == "__main__": link=None for i in range(10): link = LinkedList(i, n=None, p=link) print("双方向連結リスト"+"-"*30) print("初めに戻る") _ = link print("%d" % _.data, end="") while(_.prev): # nodeがNoneでない間回る。 _ = _.prev print(" -> %d"%_.data, end="") print() print("初めから最後へ") print("%d" % _.data, end="") while(_.next): # nodeがNoneでない間回る。 _ = _.next print(" -> %d"%_.data, end="")
出力は
双方向連結リスト------------------------------ 初めに戻る 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 初めから最後へ 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9
C++で実装
#include<iostream> using namespace std; //双方向 class Node{ public: Node* prev; Node* next; int data; Node(int data){ this->prev = NULL; this->next = NULL; this->data = data; } ~Node(){ cout << "Node DELETED" << endl; } void setNext(Node* n){ this->next = n; if((n!=NULL)&&(n->prev!=this)){ n->setPrevious(this); } } void setPrevious(Node* p){ this->prev = p; if((p!=NULL)&&(p->next!=this)){ p->setNext(this); } } }; class LinkedList{ public: Node* node; int length; LinkedList(){ this->node = NULL; this->length = 0; } ~LinkedList(){ cout << "list deleted" << endl; } void setNext(int data){ Node* n = new Node(data); if(this->node==NULL){ this->node = n; }else{ this->node->setNext(n); this->node = n; } this->length++; } void setPrevious(int data){ Node* p = new Node(data); if(this->node==NULL){ this->node = p; }else{ this->node->setPrevious(p); } this->length++; } LinkedList* next(){ if((this->node)&&(this->node->next)){ this->node = this->node->next; } return this; } LinkedList* prev(){ if((this->node)&&(this->node->prev)){ this->node = this->node->prev; } return this; } };
実行したものは以下です。
int main(void){ LinkedList* list = new LinkedList(); int i; for(i=0; i<10; i++){ list->setNext(i); } cout << "前に戻る" << endl; while(list->node->data){ cout << list->node->data << " -> "; if(list->node->prev)list->prev(); } list->prev(); cout << list->node->data << " -> "; cout << endl; cout << "次に進む" << endl; for(i=0; i<list->length; i++){ cout << list->next()->node->data << " -> "; } return 0; }
> ./a.out 前に戻る 9 -> 8 -> 7 -> 6 -> 5 -> 4 -> 3 -> 2 -> 1 -> 0 -> 次に進む 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 9 ->