柚子快报邀请码778899分享:c++ List的模拟实现

http://yzkb.51969.com/

文章目录

List的模拟实现1. 定义List节点2. 实现List类( 1 )尾插和头插( 2 )头删和尾删( 3 )链表的迭代器,构造,赋值,交换,析构clear函数链表长度和是否为空值

3. 测试List类4.代码完整版

List的模拟实现

List(列表)是一种常见的数据结构,用于存储一系列有序的元素。在本教程中,我们将通过C++语言来模拟实现一个简单的List,并提供一些基本操作,如插入、删除、遍历等。

1. 定义List节点

首先,我们需要定义一个List的节点。每个节点包含数据和指向下一个节点的指针。

template

struct ListNode

{

ListNode* _next;

ListNode* _prev;

T _data;

ListNode(const T& x= T())

: _next(nullptr)

, _prev(nullptr)

, _data(x)

{}

};

2. 实现List类

接下来,我们定义一个List类,实现一些简单的接口

( 1 )尾插和头插

这个是正常的通过调整链表的next和prev进行尾插

void push_back(const T& x)

{

Node* newnode = new Node(x);

Node* tail = _head->_prev;

tail->_next = newnode;

newnode->_prev = tail;

newnode->_next = _head;

_head->_prev = newnode;

}

而这样写头插和尾插就会显得很冗杂,所以我们单独写一个insert的函数这样头插和尾插就都可以直接通过insert来实现

void push_back(const T& x)

{

insert(end(), x);

}

void push_front(const T& x)

{

insert(begin(),x);

}

void insert(iterator pos, const T& val)

{

Node* cur = pos._node;

Node* newnode = new Node(val);

Node* prev = cur->_prev;

_size++;

//连接关系

prev->_next = newnode;

newnode->_prev = prev;

newnode->_next = cur;

cur->_prev = newnode;

}

( 2 )头删和尾删

和头插尾插类似,我们直接写list的erase的接口)头删和尾删就能顺利的写出来了

void pop_back()

{

erase(--end());

}

void pop_font()

{

erase(begin());

}

iterator erase(iterator pos)

{

Node* cur = pos._node;

Node* prev = cur->_prev;

Node* next = cur->_next;

_size--;

prev->_next = next;

next->_prev = prev;

delete cur;

return iterator(next);

}

( 3 )链表的迭代器,构造,赋值,交换,析构

构造函数 list() :

调用 empty_init() 函数初始化链表。这个函数可能设置了链表的头节点 _head 和大小 _size 。

构造函数 list(const list& lt) :

调用 empty_init() 函数初始化链表。使用范围for循环遍历传入的链表 lt ,对于每个元素,调用 push_back(e) 方法将元素添加到新链表的末尾。-

swap(list& lt) 函数:

使用 std::swap() 函数交换当前链表的头节点 _head 和大小 _size 与传入链表 lt 的相应成员变量。

赋值运算符 list& operator=(list lt) :

调用 swap(lt) 函数,将当前链表的头节点 _head 和大小 _size 与传入的链表 lt 进行交换。返回当前链表的引用,以便支持链式赋值(如 lt1 = lt2 = lt3 )。

私有成员变量:

_head :指向链表头节点的指针。_size :表示链表中元素数量的整数。

然后在写const的时候本来想法是写两个struct(即注释的部分)但是之后想到了模板函数这样我写函数的模板来进行const和非const两种迭代器就方便多了

/*typedef ListIterator iterator;

typedef ListConstIterator const_iterator;*/

//写模板,编译器生成两个类

template

struct ListIterator

{

typedef ListNode Node;

typedef ListIterator Self;

Node* _node;

ListIterator(Node* node)

:_node(node)

{}

//*it

//T& operator*()

Ref operator*()

{

return _node->_data;

}

//it->//

//T* operator->()

Ptr operator->()

{

return &_node->_data;

}

//++it

Self& operator++()

{

_node = _node->_next;

return *this;

}

//++it

Self operator++(int)

{

Self tmp(*this);

_node = _node->_next;

return tmp;

}

//--it

Self& operator--()

{

_node = _node->_prev;

return *this;

}

Self operator--(int)

{

Self tmp(*this);

_node = _node->_prev;

return tmp;

}

bool operator!=(const Self& it)

{

return _node != it._node;

}

bool operator==(const Self& it)

{

return _node == it._node;

}

};

//template

//struct ListConstIterator

//{

// typedef ListNode Node;

// typedef ListConstIterator Self;

//

// Node* _node;

//

// ListConstIterator(Node* node)

// :_node(node)

// {}

//

// //*it

// const T& operator*()

// {

// return _node->_data;

// }

//

// //it->//

// const T* operator->()

// {

// return &_node->_data;

// }

//

// //++it

// Self& operator++()

// {

// _node = _node->_next;

// return *this;

// }

//

// //++it

// Self operator++(int)

// {

// Self tmp(*this);

// _node = _node->_next;

//

// return tmp;

// }

//

// //--it

// Self& operator--()

// {

// _node = _node->_prev;

// return *this;

// }

//

// Self operator--(int)

// {

// Self tmp(*this);

// _node = _node->_prev;

//

// return tmp;

// }

//

// bool operator!=(const Self& it)

// {

// return _node != it._node;

// }

//

// bool operator==(const Self& it)

// {

// return _node == it._node;

// }

//};

template

class list

{

typedef ListNode Node;

public:

/*typedef ListIterator iterator;

typedef ListConstIterator const_iterator;*/

typedef ListIterator iterator;

typedef ListIterator const_iterator;

iterator begin()

{

//return iterator(_head->_next);

return _head->_next;

}

iterator end()

{

return _head;

}

//因为const迭代器需要的是指向的内容不能被修改,所以const iterator不能用

const_iterator begin() const

{

return _head->_next;

}

const_iterator end() const

{

return _head;

}

void empty_init()

{

_head = new Node;

_head->_next = _head;

_head->_prev = _head;

_size = 0;

}

list()

{

empty_init();

}

//lt2(lt1)

list(const list& lt)

{

empty_init();

for (auto& e : lt)

{

push_back(e);

}

}

void swap(list& lt)

{

std::swap(_head, lt._head);

std::swap(_size,lt._size);

}

//lt1 = lt3

list& operator=(list lt)

{

swap(lt);

return *this;

}

~list()

{

clear();

delete _head;

_head = nullptr;

}

private:

Node* _head;

size_t _size;

}

clear函数

就是用迭代器遍历每个节点之后通过erase进行释放

void clear()

{

iterator it = begin();

while (it != end())

{

it = erase(it);

}

}

链表长度和是否为空值

这里size我就是简单粗暴的每次push和insert就++,每次pop和erase就– 至于判空就是==0进行判断

size_t size() const

{

return _size;

}

bool empty()

{

return _size == 0;

}

3. 测试List类

现在我们来测试一下我们的List类 这里的PrintList是遍历const类弄的

void test_list1()

{

list lt;

lt.push_back(1);

lt.push_back(2);

lt.push_back(3);

lt.push_back(4);

lt.push_back(5);

list::iterator it = lt.begin();

while (it != lt.end())

{

cout << *it << " ";

it++;

}

cout << endl;

lt.push_front(10);

lt.push_front(20);

lt.push_front(30);

lt.push_front(40);

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

lt.pop_back();

lt.pop_back();

lt.pop_back();

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

lt.pop_font();

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

}

void PrintList(const list& clt)

{

list::const_iterator it = clt.begin();

while (it!=clt.end())

{

//*it += 10;

cout << *it << " ";

it++;

}

cout << endl;

}

void test_list2()

{

list lt;

lt.push_back(1);

lt.push_back(2);

lt.push_back(3);

lt.push_back(4);

lt.push_back(5);

lt.push_back(6);

PrintList(lt);

list lt1(lt);

PrintList(lt1);

/*lt.clear();

PrintList(lt);*/

}

4.代码完整版

namespace mylist

{

template

struct ListNode

{

ListNode* _next;

ListNode* _prev;

T _data;

ListNode(const T& x= T())

: _next(nullptr)

, _prev(nullptr)

, _data(x)

{}

};

/*typedef ListIterator iterator;

typedef ListConstIterator const_iterator;*/

//写模板,编译器生成两个类

template

struct ListIterator

{

typedef ListNode Node;

typedef ListIterator Self;

Node* _node;

ListIterator(Node* node)

:_node(node)

{}

//*it

//T& operator*()

Ref operator*()

{

return _node->_data;

}

//it->//

//T* operator->()

Ptr operator->()

{

return &_node->_data;

}

//++it

Self& operator++()

{

_node = _node->_next;

return *this;

}

//++it

Self operator++(int)

{

Self tmp(*this);

_node = _node->_next;

return tmp;

}

//--it

Self& operator--()

{

_node = _node->_prev;

return *this;

}

Self operator--(int)

{

Self tmp(*this);

_node = _node->_prev;

return tmp;

}

bool operator!=(const Self& it)

{

return _node != it._node;

}

bool operator==(const Self& it)

{

return _node == it._node;

}

};

//template

//struct ListConstIterator

//{

// typedef ListNode Node;

// typedef ListConstIterator Self;

//

// Node* _node;

//

// ListConstIterator(Node* node)

// :_node(node)

// {}

//

// //*it

// const T& operator*()

// {

// return _node->_data;

// }

//

// //it->//

// const T* operator->()

// {

// return &_node->_data;

// }

//

// //++it

// Self& operator++()

// {

// _node = _node->_next;

// return *this;

// }

//

// //++it

// Self operator++(int)

// {

// Self tmp(*this);

// _node = _node->_next;

//

// return tmp;

// }

//

// //--it

// Self& operator--()

// {

// _node = _node->_prev;

// return *this;

// }

//

// Self operator--(int)

// {

// Self tmp(*this);

// _node = _node->_prev;

//

// return tmp;

// }

//

// bool operator!=(const Self& it)

// {

// return _node != it._node;

// }

//

// bool operator==(const Self& it)

// {

// return _node == it._node;

// }

//};

template

class list

{

typedef ListNode Node;

public:

/*typedef ListIterator iterator;

typedef ListConstIterator const_iterator;*/

typedef ListIterator iterator;

typedef ListIterator const_iterator;

iterator begin()

{

//return iterator(_head->_next);

return _head->_next;

}

iterator end()

{

return _head;

}

//因为const迭代器需要的是指向的内容不能被修改,所以const iterator不能用

const_iterator begin() const

{

return _head->_next;

}

const_iterator end() const

{

return _head;

}

void empty_init()

{

_head = new Node;

_head->_next = _head;

_head->_prev = _head;

_size = 0;

}

list()

{

empty_init();

}

//lt2(lt1)

list(const list& lt)

{

empty_init();

for (auto& e : lt)

{

push_back(e);

}

}

void swap(list& lt)

{

std::swap(_head, lt._head);

std::swap(_size,lt._size);

}

//lt1 = lt3

list& operator=(list lt)

{

swap(lt);

return *this;

}

void clear()

{

iterator it = begin();

while (it != end())

{

it = erase(it);

}

}

~list()

{

clear();

delete _head;

_head = nullptr;

}

/*void push_back(const T& x)

{

Node* newnode = new Node(x);

Node* tail = _head->_prev;

tail->_next = newnode;

newnode->_prev = tail;

newnode->_next = _head;

_head->_prev = newnode;

}*/

void push_back(const T& x)

{

insert(end(), x);

}

void push_front(const T& x)

{

insert(begin(),x);

}

void pop_back()

{

erase(--end());

}

void pop_font()

{

erase(begin());

}

void insert(iterator pos, const T& val)

{

Node* cur = pos._node;

Node* newnode = new Node(val);

Node* prev = cur->_prev;

_size++;

//连接关系

prev->_next = newnode;

newnode->_prev = prev;

newnode->_next = cur;

cur->_prev = newnode;

}

iterator erase(iterator pos)

{

Node* cur = pos._node;

Node* prev = cur->_prev;

Node* next = cur->_next;

_size--;

prev->_next = next;

next->_prev = prev;

delete cur;

return iterator(next);

}

size_t size() const

{

return _size;

}

bool empty()

{

return _size == 0;

}

private:

Node* _head;

size_t _size;

};

void test_list1()

{

list lt;

lt.push_back(1);

lt.push_back(2);

lt.push_back(3);

lt.push_back(4);

lt.push_back(5);

list::iterator it = lt.begin();

while (it != lt.end())

{

cout << *it << " ";

it++;

}

cout << endl;

lt.push_front(10);

lt.push_front(20);

lt.push_front(30);

lt.push_front(40);

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

lt.pop_back();

lt.pop_back();

lt.pop_back();

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

lt.pop_font();

for (auto e : lt)

{

cout << e << " ";

}

cout << endl;

}

void PrintList(const list& clt)

{

list::const_iterator it = clt.begin();

while (it!=clt.end())

{

//*it += 10;

cout << *it << " ";

it++;

}

cout << endl;

}

void test_list2()

{

list lt;

lt.push_back(1);

lt.push_back(2);

lt.push_back(3);

lt.push_back(4);

lt.push_back(5);

lt.push_back(6);

PrintList(lt);

list lt1(lt);

PrintList(lt1);

/*lt.clear();

PrintList(lt);*/

}

}

看到这里可以点个赞吗? 球球了

柚子快报邀请码778899分享:c++ List的模拟实现

http://yzkb.51969.com/

精彩内容

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。