線形リストを作ってみる その2
線形リストを作ってみる その1 - white wheelsのメモの続き。
push_back(最後尾に要素を挿入する), pop_back(最後尾の要素を削除する)を加え、好きな位置のノードにアクセスできるようにしてみます。
線形リストver2
List.h
#ifndef __List_H #define __List_H #include "Node.h" class List { public: List(void); ~List(void); void push_back(int data); //要素を最後尾に追加する void pop_back(); //最後の要素を削除する void clear(); //全てのノードを削除する int operator[](unsigned int i); //i番目の要素を取り出す void print(); //要素を表示する private: void insert_next(Node* node,int data);//指定したnodeの後に追加 void insert_prev(Node* node,int data);//指定したnodeの前に追加 void erase(Node* node); //指定したノードを削除する Node* node(unsigned int i); //i番目のノードを取得する Node* m_root; int m_size; }; #endif
要素の追加と削除
前に作成したinsertを再利用します。
void List::push_back(int data){ insert_prev(m_root,data); } void List::pop_back(){ erase(m_root->prev()); }
全ノードの削除
eraseを再利用します。rootが自分自身につながっていることを確認します。
void List::clear(){ for(Node* node=m_root->next();node!=m_root;node=m_root->next()){ erase(node); } m_size=0; }
指定位置のノード・値の取得
範囲外の場合は例外処理を行う必要があります。今回はrootを返すようにしてみました。
Node* List::node(unsigned int i){ int count=0; for(Node* node=m_root->next();node!=m_root;node=node->next()){ if(count==i){ return node; } count++; } return m_root;//out of range } int List::operator[](unsigned int i){ return node(i)->data(); }
List.cpp
#include "List.h" List::List(void): m_size(0) { m_root = new Node(); m_root->next() = m_root; //rootノードの前後を自分自身にしておく m_root->prev() = m_root; } List::~List(void) { clear(); delete m_root; } int List::operator[](unsigned int i){ return node(i)->data(); } void List::push_back(int data){ insert_prev(m_root,data); } void List::pop_back(){ erase(m_root->prev()); } void List::clear(){ for(Node* node=m_root->next();node!=m_root;node=m_root->next()){ erase(node); } m_size=0; } void List::insert_next(Node* node,int data){ if(node==0){ return; } Node* new_node=new Node();//新たに追加したnode new_node->prev()=node; new_node->next()=node->next(); node->next()->prev()=new_node; node->next()=new_node; new_node->data()=data; //追加したnodeの値を設定 m_size++; } void List::insert_prev(Node* node,int data){ if(node==0){ return; } Node* new_node=new Node();//新たに追加したnode new_node->prev()=node->prev(); new_node->next()=node; node->prev()->next()=new_node; node->prev()=new_node; new_node->data()=data;//追加したnodeの値を設定 m_size++; } void List::erase(Node* node){ if(node==0 || node==m_root){ //rootは削除しない return; } node->prev()->next()=node->next(); node->next()->prev()=node->prev(); delete node; m_size--; } Node* List::node(unsigned int i){ int count=0; for(Node* node=m_root->next();node!=m_root;node=node->next()){ if(count==i){ return node; } count++; } return m_root;//out of range } #include <iostream> using namespace std; //要素を表示する void List::print(){ cout <<"(root) "<<"\t\t"; m_root->print(); int count=0; for(Node* node=m_root->next();node!=m_root;node=node->next()){ cout <<"(node"<<count<<") "<<"\t"; node->print(); count++; } }
線形リストクラスの利用
#include "List.h" #include <iostream> using namespace std; int main(){ List list; list.print(); cout << endl; list.push_back(1); list.print(); cout << endl; list.push_back(2); list.print(); cout << endl; list.push_back(3); list.print(); cout << endl; list.pop_back(); list.print(); cout << endl; cout<<list[1]<<endl;; list.clear(); list.print(); cout << endl; list.pop_back(); list.print(); cout << endl; cout<<list[2]<<endl;; return 0; }
(root) prev[00868FC8] [00868FC8,data=0] next[00868FC8]
(root) prev[00862328] [00868FC8,data=0] next[00862328]
(node0) prev[00868FC8] [00862328,data=1] next[00868FC8]
(root) prev[00862360] [00868FC8,data=0] next[00862328]
(node0) prev[00868FC8] [00862328,data=1] next[00862360]
(node1) prev[00862328] [00862360,data=2] next[00868FC8]
(root) prev[00862398] [00868FC8,data=0] next[00862328]
(node0) prev[00868FC8] [00862328,data=1] next[00862360]
(node1) prev[00862328] [00862360,data=2] next[00862398]
(node2) prev[00862360] [00862398,data=3] next[00868FC8]
(root) prev[00862360] [00868FC8,data=0] next[00862328]
(node0) prev[00868FC8] [00862328,data=1] next[00862360]
(node1) prev[00862328] [00862360,data=2] next[00868FC8]
2
(root) prev[00868FC8] [00868FC8,data=0] next[00868FC8]
(root) prev[00868FC8] [00868FC8,data=0] next[00868FC8]
0