Der Unterschied zwischen Vektor und Liste
● Vektor hat eine hohe Direktzugriffseffizienz, muss aber beim Einfügen und Löschen verschoben werden (ausgenommen der Schwanz) Daten sind schwer zu manipulieren.
●Der Listenzugriff erfordert das Durchlaufen der gesamten verknüpften Liste und die Effizienz des Direktzugriffs ist gering. Es ist jedoch bequemer, Daten einzufügen und zu löschen, indem Sie einfach die Ausrichtung des Zeigers ändern.
● Liste ist unidirektional, Vektor ist bidirektional.
● Der Iterator im Vektor wird nach der Verwendung ungültig, während der Iterator in der Liste nach der Verwendung weiterhin verwendet werden kann.
Verwendung von Vektoren
Kontinuierliche Speicherstruktur: Vektor ist ein Objektarray, das ein dynamisches Wachstum erreichen kann und einen effizienten Zugriff auf das Array sowie das Löschen und Einfügen am Ende unterstützt Die Array-Operation, das Löschen und Einfügen in der Mitte und im Kopf ist relativ schwierig und erfordert das Verschieben einer großen Datenmenge. Der größte Unterschied zwischen ihr und einem Array besteht darin, dass Programmierer nicht selbst über Kapazitätsprobleme nachdenken müssen. Die Bibliothek selbst hat bereits ein dynamisches Kapazitätswachstum realisiert, während bei Arrays Programmierer manuell Erweiterungsfunktionen schreiben müssen, um die Kapazität zu erweitern.
Simulationsimplementierung von Vector
template <class T> class Vector { public: typedef T* Iterator; typedef const T* Iterator; Vector() :_start(NULL) ,_finish(NULL) ,_endOfStorage(NULL) {} void template<class T> PushBack(const T& x) { Iterator end = End(); Insert(end, x); } void Insert(Iterator& pos, const T& x) { size_t n = pos - _start; if (_finish == _endOfStorage) { size_t len = Capacity() == 0 ? 3 : Capacity()*2; Expand(len); } pos = _start+n; for (Iterator end = End(); end != pos; --end) { *end = *(end-1); } *pos = x; ++_finish; } Iterator End() { return _finish; } Iterator Begin() { return _start; } void Resize(size_t n, const T& val = T())//用Resize扩容时需要初始化空间,并且可以缩小容量 { if (n < Size()) { _finish = _start+n; } else { Reserve(n); size_t len = n-Size(); for (size_t i = 0; i < len; ++i) { PushBack(val); } } } void Reserve(size_t n)//不用初始化空间,直接增容 { Expand(n); } inline size_t Size() { return _finish-_start; } inline size_t Capacity() { return _endOfStorage-_start; } void Expand(size_t n) { const size_t size = Size(); const size_t capacity = Capacity(); if (n > capacity) { T* tmp = new T[n]; for (size_t i = 0; i < size; ++i) { tmp[i] = _start[i]; } delete[] _start; _start = tmp; _finish = _start+size; _endOfStorage = _start+n; } } T& operator[](size_t pos) { assert(pos < Size()); return _start[pos]; } const T& operator[](size_t pos) const { assert(pos < Size()); return _start[pos]; } protected: Iterator _start; //指向第一个元素所在节点 Iterator _finish; //指向最后一个元素所在节点的下一个节点 Iterator _endOfStorage; //可用内存空间的末尾节点 };
Verwendung von Listen
Nicht kontinuierliche Speicherstruktur: Liste ist eine doppelt verknüpfte Listenstruktur, die das bidirektionale Durchlaufen von unterstützt die verlinkte Liste. Jeder Knoten enthält drei Informationen: das Element selbst, den Knoten, der auf das vorherige Element zeigt (prev), und den Knoten, der auf das nächste Element zeigt (next). Daher kann die Liste an jedem Ort effizient auf Datenelemente zugreifen, diese einfügen und löschen. Da es sich um die Pflege zusätzlicher Zeiger handelt, ist der Overhead relativ hoch.
Simulationsimplementierung von List
template<class T> class List { typedef __ListNode<T> Node; public: typedef __ListIterator<T, T&, T*> Iterator; typedef __ListIterator<T, const T&, const T*> ConstIterator; Iterator Begin() { return _head->_next; } Iterator End() { return _head; } ConstIterator Begin() const { return _head->_next; } ConstIterator End() const { return _head; } List() { _head = new Node(T()); _head->_next = _head; _head->_prev = _head; } // l2(l1) List(const List& l) { _head = new Node(T()); _head->_next = _head; _head->_prev = _head; ConstIterator it = l.Begin(); while (it != l.End()) { PushBack(*it); ++it; } } ~List() { Clear(); delete _head; _head = NULL; } void Clear() { Iterator it = Begin(); while (it != End()) { Node* del = it._node; ++it; delete del; } _head->_next = _head; _head->_prev = _head; } void PushBack(const T& x) { Insert(End(), x); } void PushFront(const T& x) { Insert(Begin(), x); } void PopBack() { Erase(--End()); } void PopFront() { Erase(Begin()); } void Insert(Iterator pos, const T& x) { Node* cur = pos._node; Node* prev = cur->_prev; Node* tmp = new Node(x); prev->_next = tmp; tmp->_prev = prev; tmp->_next = cur; cur->_prev = prev; } Iterator Erase(Iterator& pos) { assert(pos != End()); Node* prev = (pos._node)->_prev; Node* next = (pos._node)->_next; prev->_next = next; next->_prev = prev; delete pos._node; pos._node = prev; return Iterator(next); } protected: Node* _head; };
Empfohlenes Lernen: Java-Video-Tutorial
Das obige ist der detaillierte Inhalt vonWas ist der Unterschied zwischen Vektor und Liste in Java?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!