顺序存储
#include <iostream>
template <typename T>
class List
{
private:
const int LIST_INIT_SIZE = 100;
T *_elem;
int _length = 0;
int _capacity = LIST_INIT_SIZE;
public:
List();
List(std::initializer_list<T>);
~List();
void Clear();
bool isEmpty();
int length();
T operator[](int) const;
T &operator[](int);
template <typename F>
int locateElem(T, F) const;
int priorElem(T) const;
int nextElem(T) const;
bool listInsert(int, T);
bool listDelete(int, T &);
template <typename F>
void traverse(F);
void expand();
void shrink();
class iterator
{
private:
T *_m_ptr;
public:
iterator(T *pt = nullptr) : _m_ptr(pt){}
T operator*() const { return *_m_ptr; }
T* operator->() const { return *_m_ptr; }
T* operator++(int)
{ T *m_ptr = _m_ptr;
_m_ptr++;
return m_ptr;
}
T* operator++()
{
_m_ptr++;
return _m_ptr;
}
bool operator==(const iterator &iter) const { return _m_ptr == iter._m_ptr; }
bool operator!=(const iterator &iter) const { return _m_ptr != iter._m_ptr; }
};
iterator begin() { return iterator(_elem); }
iterator end() { return iterator(_elem + _length); }
};
template <typename T>
void MergeList(T La, T Lb, T &Lc)
{
int i = 0;
int j = 0;
int k = 0;
while (i != La.length() && j != Lb.length())
{
if (La[i] <= Lb[j])
{
Lc.listInsert(k, La[i]);
i++;
k++;
}
else if (La[i] > Lb[j])
{
Lc.listInsert(k, Lb[j]);
j++;
k++;
}
}
while (i != La.length())
{
Lc.listInsert(k, La[i]);
k++;
i++;
}
while (j != Lb.length())
{
Lc.listInsert(k, Lb[j]);
k++;
j++;
}
}
template <typename T>
List<T>::List() { _elem = new T[LIST_INIT_SIZE]; }
template <typename T>
List<T>::List(std::initializer_list<T> ls) : List()
{
int i = 0;
for (auto p = ls.begin(); p != ls.end(); p++, i++)
listInsert(i, *p);
}
template <typename T>
List<T>::~List() { delete[] _elem; }
template <typename T>
void List<T>::Clear()
{
delete[] _elem;
_length = 0;
_capacity = LIST_INIT_SIZE;
_elem = new T[LIST_INIT_SIZE];
}
template <typename T>
bool List<T>::isEmpty() { return !_length; }
template <typename T>
int List<T>::length() { return _length; }
template <typename T>
T List<T>::operator[](int i) const { return _elem[i]; }
template <typename T>
T &List<T>::operator[](int i) { return _elem[i]; }
template <typename T>
template <typename F>
int List<T>::locateElem(T i, F f) const
{
for (int j = 0; j < _length; j++)
if (f(i, _elem[j]))
return j;
return -1;
}
template <typename T>
int List<T>::priorElem(T t) const
{
if (_length == 1)
return -1;
for (int i = 1; i < _length; i++)
if (t == _elem[i])
return i - 1;
return -1;
}
template <typename T>
int List<T>::nextElem(T t) const
{
if (_length == 1)
return -1;
for (int i = 0; i < _length - 1; i++)
if (t == _elem[i])
return i + 1;
return -1;
}
template <typename T>
bool List<T>::listInsert(int l, T t)
{
expand();
if (l == _length)
{
_elem[l] = t;
_length++;
return true;
}
if (l < 0 || l > _length - 1)
return false;
for (int i = _length - 1; i >= l; i--)
_elem[i + 1] = _elem[i];
_elem[l] = t;
_length++;
return true;
}
template <typename T>
bool List<T>::listDelete(int l, T &t)
{
if (l < 0 || l > _length - 1)
return false;
t = _elem[l];
if (l == _length - 1)
return true;
for (int i = l + 1; i < _length; i++)
_elem[i - 1] = _elem[i];
_length--;
shrink();
return true;
}
template <typename T>
template <typename F>
void List<T>::traverse(F f)
{
for (int i = 0; i < _length; i++)
f(_elem[i]);
}
template <typename T>
void List<T>::expand()
{
if (_capacity - _length >= 10)
return;
_capacity += 10;
T *oldElem = _elem;
_elem = new T[_capacity];
for (int i = 0; i < _length; i++)
_elem[i] = oldElem[i];
delete[] oldElem;
}
template <typename T>
void List<T>::shrink()
{
if (_capacity - _length <= 10)
return;
_capacity -= 10;
T *oldElem = _elem;
_elem = new T[_capacity];
for (int i = 0; i < _length; i++)
_elem[i] = oldElem[i];
delete[] oldElem;
}
int main()
{
using std::cout;
using std::endl;
List<int> test{1, 2, 3, 4, 5};
for (auto p = test.begin(); p != test.end(); p++)
cout << *p << " ";
cout << "MergeList()测试:" << endl;
List<int> La = {1, 3, 5, 7, 7, 9};
List<int> Lb = {2, 4, 6, 8, 10};
List<int> Lc;
MergeList(La, Lb, Lc);
for (int i = 0; i < Lc.length(); i++)
cout << Lc[i] << " ";
cout << endl << "length():" << endl;
cout << "the length of list : " << test.length() << endl;
cout << endl
<< "operator[]()" << endl;
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl
<< "locateElem()" << endl;
cout << test.locateElem(3, [](int i, int e) { return i == e + 1; }) << endl;
cout << endl
<< "priorElem()" << endl;
cout << test.priorElem(2) << endl;
cout << endl
<< "nextElem()" << endl;
cout << test.nextElem(4) << endl;
cout << endl
<< "listInsert()" << endl;
test.listInsert(3, 3);
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl
<< "listDelete()" << endl;
int n = 0;
test.listDelete(3, n);
cout << n << endl;
cout << endl
<< "traverse()" << endl;
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl;
test.traverse([](int &i) { i <<= 1; });
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
test.Clear();
if (test.isEmpty()){
cout << endl
<< "list已经空了。";
}
}
链式存储
#include<iostream>
#include<stdexcept>
template<typename T>
class List
{
struct Node
{
T data;
Node* next;
};
private:
Node* _head;
Node* _rear;
int _length = 0;
public:
List();
List(std::initializer_list<T>);
~List();
void Clear();
bool isEmpty();
int length();
T operator[](int) const;
T& operator[](int);
template <typename F>
int locateElem(T, F) const;
int priorElem(T) const;
int nextElem(T) const;
bool listInsert(int, T);
bool listDelete(int, T&);
template <typename F>
void traverse(F);
};
template<typename T>
List<T>::List()
{
_head = nullptr;
_rear = nullptr;
}
template<typename T>
List<T>::List(std::initializer_list<T> ls) :List()
{
int i = 0;
for (auto p = ls.begin(); p != ls.end(); p++, i++)
listInsert(i, *p);
}
template <typename T>
List<T>::~List() { Clear(); }
template<typename T>
void List<T>::Clear()
{
Node* p = _head;
Node* preNode = nullptr;
while (p)
{
preNode = p;
p = p->next;
delete preNode;
}
_head = nullptr;
_rear = nullptr;
_length = 0;
}
template <typename T>
bool List<T>::isEmpty() { return !_length; }
template <typename T>
int List<T>::length() { return _length; }
template <typename T>
T List<T>::operator[](int l) const
{
if (l < 0 || l > _length - 1)
throw std::out_of_range("out of range error");
Node* p = _head;
int i = 0;
while (i != l)
{
p = p->next;
i++;
}
return p->data;
}
template<typename T>
T& List<T>::operator[](int l)
{
if (l < 0 || l > _length - 1)
throw std::out_of_range("out of range error");
Node* p = _head;
int i = 0;
while (i != l)
{
p = p->next;
i++;
}
return p->data;
}
template<typename T>
template<typename F>
int List<T>::locateElem(T t, F f) const
{
for (int i = 0; i < _length; i++)
if (f(t, this->operator[](i)))
return i;
return -1;
}
template<typename T>
int List<T>::priorElem(T t) const
{
for (int i = 1; i < _length; i++)
if (this->operator[](i) == t)
return i - 1;
return -1;
}
template<typename T>
int List<T>::nextElem(T t) const
{
for (int i = 0; i < _length - 1; i++)
if (this->operator[](i) == t)
return i + 1;
return -1;
}
template<typename T>
bool List<T>::listInsert(int l, T t)
{
if (l < 0 || l > _length)
return false;
Node* newItem = new Node;
newItem->data = t;
newItem->next = nullptr;
_length++;
if (l == 0)
{
newItem->next = _head;
_head = newItem;
return true;
}
Node* Prep = _head;
int i = 1;
while (i != l)
{
Prep = Prep->next;
i++;
}
newItem->next = Prep->next;
Prep->next = newItem;
return true;
}
template<typename T>
bool List<T>::listDelete(int l, T& t)
{
if (l < 0 || l > _length - 1)
return false;
_length--;
if (l == 0)
{
Node* p = _head;
_head = _head->next;
delete p;
return true;
}
int i = 1;
Node* Prep = _head;
while (i != l)
{
Prep = Prep->next;
i++;
}
Node* p = Prep->next;
Prep->next = p->next;
delete p;
return true;
}
template<typename T>
template<typename F>
void List<T>::traverse(F f)
{
for (int i = 0; i < _length; i++)
f(this->operator[](i));
}
int main()
{
using std::cout;
using std::endl;
List<int> test{ 1, 2, 3, 4, 5 };
cout << endl << "length():" << endl;
cout << "the length of list : " << test.length() << endl;
cout << endl
<< "operator[]()" << endl;
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl
<< "locateElem()" << endl;
cout << test.locateElem(3, [](int i, int e) { return i == e + 1; }) << endl;
cout << endl
<< "priorElem()" << endl;
cout << test.priorElem(2) << endl;
cout << endl
<< "nextElem()" << endl;
cout << test.nextElem(4) << endl;
cout << endl
<< "listInsert()" << endl;
test.listInsert(3, 3);
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl
<< "listDelete()" << endl;
int n = 0;
test.listDelete(3, n);
cout << n << endl;
cout << endl
<< "traverse()" << endl;
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
cout << endl;
test.traverse([](int& i) { i <<= 1; });
for (int i = 0; i < test.length(); i++)
cout << test[i] << " ";
test.Clear();
if (test.isEmpty()) {
cout << endl
<< "list已经空了。";
}
}