当前位置: 首页 > wzjs >正文

网站开发的常见编程语言有哪些站长友情链接平台

网站开发的常见编程语言有哪些,站长友情链接平台,网站开发的发展趋势,微信导航网站怎么做目录 1. list 的基本结构 1.1 构造函数 2. 迭代器的实现 2.1 构造函数 2.2 自增和自减操作符 2.3 比较操作符 2.4 解引用和箭头操作符 3. list 容器的实现 3.1 构造函数 3.2 拷贝构造 3.3 赋值运算符重载 3.4 析构函数 3.5 迭代器相关函数 3.6 插入和删除函数 3.…

目录

1. list 的基本结构

1.1 构造函数

2. 迭代器的实现

2.1 构造函数

2.2 自增和自减操作符

2.3 比较操作符

2.4 解引用和箭头操作符

3. list 容器的实现

3.1 构造函数

3.2 拷贝构造

3.3 赋值运算符重载

3.4 析构函数

3.5 迭代器相关函数

3.6 插入和删除函数

3.7 其他函数

4. 测试代码

5. 源码 


1. list 的基本结构

list 是一个双向链表,每个节点包含两个指针,分别指向其前驱节点和后继节点。我们首先定义一个 ListNode 结构来表示链表中的节点。

template<class T>
struct ListNode
{ListNode<T>* _next;   // 指向后继节点ListNode<T>* _prev;   // 指向前驱节点T _data;              // 节点存储的数据// 构造函数ListNode(const T& x = T()):_next(nullptr),_prev(nullptr),_data(x){}
};

1.1 构造函数

构造函数用于初始化节点。如果未传入数据,则使用默认构造函数初始化数据域。前驱和后继指针初始化为 nullptr

ListNode(const T& x = T()):_next(nullptr),_prev(nullptr),_data(x)
{}

2. 迭代器的实现

为了方便遍历链表,我们需要定义一个迭代器结构。迭代器需要支持基本的操作,如解引用、自增、自减等。

template<class T, class Ref, class Ptr>
struct ListIterator
{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;  // 当前节点指针// 构造函数ListIterator(Node* node):_node(node){}// 解引用操作符Ref operator*(){return _node->_data;}// 箭头操作符Ptr operator->(){return &_node->_data;}// 前置自增Self& operator++(){_node = _node->_next;return *this;}// 后置自增Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}// 前置自减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;}
};

2.1 构造函数

迭代器的构造函数接收一个节点指针,并将其存储在 _node 中。

ListIterator(Node* node):_node(node)
{}

2.2 自增和自减操作符

自增和自减操作符分别用于移动迭代器到下一个或前一个节点。

Self& operator++()
{_node = _node->_next;return *this;
}Self operator++(int)
{Self tmp(*this);_node = _node->_next;return tmp;
}Self& operator--()
{_node = _node->_prev;return *this;
}Self operator--(int)
{Self tmp(*this);_node = _node->_prev;return tmp;
}

2.3 比较操作符

比较操作符用于判断两个迭代器是否指向同一个节点。

bool operator!=(const Self& it)
{return _node != it._node;
}bool operator==(const Self& it)
{return _node == it._node;
}

2.4 解引用和箭头操作符

解引用和箭头操作符用于访问节点中的数据。

Ref operator*()
{return _node->_data;
}Ptr operator->()
{return &_node->_data;
}

3. list 容器的实现

list 容器需要管理链表的头节点,并提供插入、删除、遍历等操作。

template<class T>
class list
{
public:typedef ListNode<T> Node;typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;// 迭代器相关函数iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}// 构造函数list(){empty_init();}// 拷贝构造list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}// 赋值运算符重载list<T>& operator=(list<T>& lt){swap(lt);return *this;}// 析构函数~list(){clear();delete _head;_head = nullptr;}// 插入、删除函数void insert(iterator pos, const T& val){Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;}iterator erase(iterator pos){Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);}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_front(){erase(begin());}// 其他函数size_t size() const{return _size;}bool empty(){return _size == 0;}void clear(){iterator it = begin();while (it != end()){it = erase(it);}}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}private:Node* _head;  // 指向链表头结点的指针size_t _size; // 链表大小// 初始化空链表void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}
};

3.1 构造函数

  • 初始化一个空链表,确保链表的头节点 _head 被正确创建。

  • 头节点的前驱和后继指针都指向自身,形成一个循环链表。

  • 初始化 _size 为 0,表示链表为空。

// 初始化空链表
void empty_init()
{_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;
}
list()
{empty_init();
}

3.2 拷贝构造

  • 首先调用 empty_init() 初始化一个空链表。

  • 遍历源列表 lt,将每个元素通过 push_back 插入到新列表中。

  • 这种方式确保新列表与源列表具有相同的元素顺序。

list(const list<T>& lt)
{empty_init();for (auto& e : lt){push_back(e);}
}

3.3 赋值运算符重载

赋值运算符重载函数通过交换两个列表的头节点来实现高效赋值。

  • 通过交换两个列表的头节点 _head 和大小 _size,可以高效地完成赋值操作。

  • 这种方式避免了逐个元素的复制,提高了效率。

  • 调用 swap 函数后,原列表的内容被交换到当前列表中。

list<T>& operator=(list<T>& lt)
{swap(lt);return *this;
}

3.4 析构函数

  • 首先调用 clear() 清空列表,释放所有节点。

  • 删除头节点 _head,并将其置为 nullptr,避免悬空指针。

~list()
{clear();delete _head;_head = nullptr;
}

3.5 迭代器相关函数

  • begin() 返回头节点的下一个节点,即第一个有效节点。

  • end() 返回头节点本身,表示迭代的结束位置。

iterator begin()
{return _head->_next;
}iterator end()
{return _head;
}

3.6 插入和删除函数

insert 函数在指定位置插入一个新节点。

  • 获取当前节点 cur 和其前驱节点 prev

  • 创建一个新节点 newnode,并初始化其数据和指针。

  • 调整 prev cur 的指针,将新节点插入到链表中。

  • 更新链表大小 _size

void insert(iterator pos, const T& val)
{Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++;
}

erase 函数删除指定位置的节点。

  • 获取当前节点 cur、其前驱节点 prev 和后继节点 next

  • 调整 prev next 的指针,绕过当前节点。

  • 删除当前节点 cur,并更新链表大小 _size

  • 返回下一个节点的迭代器,方便链式操作。

iterator erase(iterator pos)
{Node* cur = pos._node;Node* next = cur->_next;Node* prev = cur->_prev;prev->_next = next;next->_prev = prev;delete cur;_size--;return iterator(next);// 返回下一位置迭代器
}

3.7 其他函数

push_back pop_back 分别用于尾插和尾删。

  • push_back 调用 insert 在链表末尾插入新节点。

  • pop_back 调用 erase 删除链表末尾的节点。

void push_back(const T& x)
{insert(end(), x);
}void pop_back()
{erase(--end());
}

push_front pop_front 分别用于头插和头删。

  • push_front 调用 insert 在链表头部插入新节点。

  • pop_front 调用 erase 删除链表头部的节点。

void push_front(const T& x)
{insert(begin(), x);
}void pop_front()
{erase(begin());
}

size 函数返回列表中有效节点的数量。

  • 直接返回链表大小 _size,提供高效的大小查询。

size_t size() const
{return _size;
}

empty 函数判断列表是否为空。

  • 检查链表大小 _size 是否为 0,快速判断链表是否为空。

bool empty()
{return _size == 0;
}

clear 函数清空列表。

  • 遍历链表,逐个删除节点,直到链表为空。

void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}

swap 函数交换两个列表的头节点。

  • 通过交换头节点和大小,高效地交换两个列表的内容。

void swap(list<T>& lt)
{std::swap(_head, lt._head);std::swap(_size, lt._size);
}

4. 测试代码

void test_list1()
{// 基础功能测试list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);// 遍历输出list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;// 添加元素lt.push_back(10);lt.push_back(20);lt.push_front(30);lt.push_front(40);// 使用范围 for 遍历for (auto e : lt){cout << e << " ";}cout << endl;// 删除元素lt.pop_back();lt.pop_back();lt.pop_front();lt.pop_front();// 再次遍历输出for (auto e : lt){cout << e << " ";}cout << endl;
}// 自定义类型测试
struct A
{int _a1;int _a2;A(int a1 = 0, int a2 = 0):_a1(a1),_a2(a2){}
};void test_list2()
{list<A> lt;A aa1(2, 2);A aa2 = {3, 3};lt.push_back(aa1);lt.push_back(aa2);lt.push_back(A(4, 4));lt.push_back({5, 5});lt.push_back({6, 6});// 遍历输出结构体成员list<A>::iterator it = lt.begin();while (it != lt.end()){cout << it->_a1 << ":" << it->_a2 << endl;++it;}
}void PrintList(const list<int>& clt)
{list<int>::const_iterator it = clt.begin();while (it != clt.end()){cout << *it << " ";++it;}cout << endl;
}void test_list3()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int> lt1(lt);PrintList(lt1);
}

5. 源码 

#pragma once // 防止头文件重复包含#include <assert.h> // 断言相关函数
#include <iostream> // 输入输出流
using namespace std;namespace lv // 命名空间lv
{// 链表节点模板类template<class T>struct ListNode{ListNode<T>* _next; // 后继指针ListNode<T>* _prev; // 前驱指针T _data;            // 数据域// 构造函数,初始化节点,默认数据为T类型的默认构造值ListNode(const T& x = T()):_next(nullptr),_prev(nullptr),_data(x){}};// 链表迭代器模板类(泛型设计,支持普通/const迭代器)template<class T, class Ref, class Ptr>struct ListIterator{typedef ListNode<T> Node;          // 节点类型别名typedef ListIterator<T, Ref, Ptr> Self; // 自身类型别名Node* _node; // 当前节点指针// 构造函数,用给定节点指针初始化迭代器ListIterator(Node* node):_node(node){}// 解引用运算符,返回数据引用(Ref可能是T&或const T&)Ref operator*(){return _node->_data;}// 箭头运算符,返回数据指针(Ptr可能是T*或const T*)Ptr operator->(){return &_node->_data;}// 前置++,移动到下一个节点Self& operator++(){_node = _node->_next;return *this;}// 后置++,返回旧值并移动到下一个节点Self operator++(int){Self tmp(*this);_node = _node->_next;return tmp;}// 前置--,移动到前一个节点Self& operator--(){_node = _node->_prev;return *this;}// 后置--,返回旧值并移动到前一个节点Self operator--(int){Self tmp(*this);_node = _node->_prev;return tmp;}// 比较运算符,判断两个迭代器是否指向不同节点bool operator!=(const Self& it) const{return _node != it._node;}// 比较运算符,判断两个迭代器是否指向相同节点bool operator==(const Self& it) const{return _node == it._node;}};// 双向链表模板类template<class T>class list{typedef ListNode<T> Node; // 节点类型别名public:// 迭代器类型定义typedef ListIterator<T, T&, T*> iterator;             // 可修改迭代器typedef ListIterator<T, const T&, const T*> const_iterator; // 不可修改迭代器// 获取指向第一个元素的迭代器iterator begin(){return _head->_next;}// 获取尾后迭代器(指向头节点)iterator end(){return _head;}// 获取指向第一个元素的const迭代器const_iterator begin() const{return _head->_next;}// 获取尾后const迭代器const_iterator end() const{return _head;}// 初始化空链表(创建头节点并自环)void empty_init(){_head = new Node;      // 创建头节点_head->_next = _head;  // 后继指向自己_head->_prev = _head;  // 前驱指向自己_size = 0;             // 初始化元素个数}// 默认构造函数list(){empty_init();}// 拷贝构造函数(深拷贝)list(const list<T>& lt){empty_init();for (const auto& e : lt) // 遍历源链表元素{push_back(e);       // 将元素逐个插入新链表}}// 交换两个链表的内容void swap(list<T>& lt){std::swap(_head, lt._head); // 交换头指针std::swap(_size, lt._size); // 交换元素个数}// 赋值运算符(通过拷贝交换实现)list<T>& operator=(const list<T>& lt){if (this != &lt) // 防止自赋值{list<T> tmp(lt); // 拷贝构造临时对象swap(tmp);       // 交换当前对象与临时对象}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){insert(end(), x); // 在end()前插入}// 在链表头部插入元素void push_front(const T& x){insert(begin(), x); // 在begin()前插入}// 删除尾部元素void pop_back(){erase(--end()); // 删除end()的前一个元素}// 删除头部元素void pop_front(){erase(begin()); // 删除第一个元素}// 在pos位置前插入元素iterator insert(iterator pos, const T& val){Node* cur = pos._node;  // 当前节点Node* newnode = new Node(val); // 创建新节点Node* prev = cur->_prev; // 前驱节点// 调整指针连接prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;_size++; // 元素计数增加return iterator(newnode); // 返回指向新节点的迭代器}// 删除pos位置的元素iterator erase(iterator pos){assert(pos != end()); // 确保不删除头节点Node* cur = pos._node; // 当前节点Node* next = cur->_next; // 后继节点Node* prev = cur->_prev; // 前驱节点// 调整指针连接prev->_next = next;next->_prev = prev;delete cur;     // 释放节点_size--;        // 元素计数减少return iterator(next); // 返回后继节点的迭代器}// 获取链表元素个数size_t size() const{return _size;}// 判断链表是否为空bool empty(){return _size == 0;}private:Node* _head;  // 头节点指针size_t _size; // 元素个数};
}
http://www.dtcms.com/wzjs/529590.html

相关文章:

  • 有空间与域名 怎么做网站免费做网站推广的软件
  • 自适应网站运动div如何设置的百度浏览器下载安装2023版本
  • 怎么做网站赌博网站建设哪家好
  • 餐饮招商加盟网站建设私域运营软件
  • 视频直播间话术链接优化方法
  • 惠州seo网站排名google推广教程
  • 温州最好的网站建设公司seo网络优化师招聘
  • 乐清网站制作网站赚钱
  • 济南专业做公司网站的机构网站内部链接优化方法
  • 深圳住 建设局网站首页收录
  • wordpress 网站的占有seo案例分析及解析
  • 深圳网站建设相关推荐百度一下 你就知道首页
  • 南昌高端网站建设正规推广平台
  • 前端网站重构怎么做自动app优化官网
  • 网站开发与设计.net活动策划方案
  • 做网站要素百度seo免费推广教程
  • 郑州电力高等专科学校招生网网站seo优化方法
  • 重庆建设网站的公司哪家好seo建站收费地震
  • wordpress不显示categoryseo 排名 优化
  • 论坛网站建设多少钱怎么给网站做优化
  • 专业网站建设首选公司b2b平台有哪几个
  • 做微信商城网站建设抖音seo搜索引擎优化
  • 网站建设合同验收我赢网seo优化网站
  • 山东网站排行如何做免费网站推广
  • 营销网站做推广公司怎么制作seo搜索优化
  • 给一个公司做网站维护bt最佳磁力搜索引擎
  • 定制型网站系统优化
  • 有免费做网站的吗百度提交网址入口
  • 随州网站建设哪家专业电子商务网站
  • 学做网站课程谷歌推广费用多少