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

网站建设书籍下载九九建筑网

网站建设书籍下载,九九建筑网,wordpress 和 wix,公关策划公司是干什么的数据结构第三篇 一、几个注意点 1、同时持有头尾结点的引用 双链表一般同时持有头尾结点的引用 因为在工程应用中,通常在容器尾插入元素,双链表持有尾部节点的引用,就可以在O(1)时间复杂度的情况下在尾部添加元素。…

数据结构第三篇

一、几个注意点

1、同时持有头尾结点的引用

双链表一般同时持有头尾结点的引用

因为在工程应用中,通常在容器尾插入元素,双链表持有尾部节点的引用,就可以在O(1)时间复杂度的情况下在尾部添加元素。

对于单链表,持有尾节点的引用也有优化效果,比如在单链表尾部添加元素;如果没有尾部节点的引用,就需要遍历整个链表找到尾部节点,时间复杂度O(n);如果有尾部节点的引用,就可以在O(1)的时间复杂度内完成尾部添加元素的操作;如果删除一次单链表的尾节点,那么之前的尾节点的引用就会失效,还需要遍历一次才能找到尾节点?但是其实,可以更新尾结点的引用

2、虚拟头尾结点

在创建双链表时,创建一个虚拟的头尾结点,无论双链表是否为空,这两个结点都存在,这样就不会出现空指针的问题,避免边界处理的问题。

空的双链表:

dummyHead <-> dummyTail

添加两个元素:

dummyHead <-> 1 <-> 2 <-> dummyTail

之前需要在头部插入元素,需要分类讨论,现在有了虚拟头尾结点,无论是否为空,都不需要分类讨论。

注意:虚拟头尾结点是对外不可见的

3、内存泄漏

// 假设单链表头结点 head = 1 -> 2 -> 3 -> 4 -> 5
// 删除单链表头结点
head = head.next;  // 此时 head = 2 -> 3 -> 4 -> 5

删除结点,最好是把删除的结点都设为null

二、代码实现

1、双链表
#include <iostream>
#include <stdexcept>template<typename E>
class MyLinkedList {// 虚拟头尾节点struct Node {E val;Node* next;Node* prev;Node(E value) : val(value), next(nullptr), prev(nullptr) {}};Node* head;Node* tail;int size;public:// 构造函数初始化虚拟头尾节点MyLinkedList() {head = new Node(E());tail = new Node(E());head->next = tail;tail->prev = head;size = 0;}// ***** 增 *****void addLast(E e) {Node* x = new Node(e);Node* temp = tail->prev;// temp <-> xtemp->next = x;x->prev = temp;x->next = tail;tail->prev = x;// temp <-> x <-> tailsize++;}void addFirst(E e) {Node* x = new Node(e);Node* temp = head->next;// head <-> temptemp->prev = x;x->next = temp;head->next = x;x->prev = head;// head <-> x <-> tempsize++;}void add(int index, E element) {checkPositionIndex(index);if (index == size) {addLast(element);return;}// 找到 index 对应的 NodeNode* p = getNode(index);Node* temp = p->prev;// temp <-> p// 新要插入的 NodeNode* x = new Node(element);p->prev = x;temp->next = x;x->prev = temp;x->next = p;// temp <-> x <-> psize++;}// ***** 删 *****E removeFirst() {if (size < 1) {throw std::out_of_range("No elements to remove");}// 虚拟节点的存在是我们不用考虑空指针的问题Node* x = head->next;Node* temp = x->next;// head <-> x <-> temphead->next = temp;temp->prev = head;E val = x->val;delete x;// head <-> tempsize--;return val;}E removeLast() {if (size < 1) {throw std::out_of_range("No elements to remove");}Node* x = tail->prev;Node* temp = tail->prev->prev;// temp <-> x <-> tailtail->prev = temp;temp->next = tail;E val = x->val;x->prev = null;x->next = null;delete x;// temp <-> tailsize--;return val;}E remove(int index) {checkElementIndex(index);// 找到 index 对应的 NodeNode* x = getNode(index);Node* prev = x->prev;Node* next = x->next;// prev <-> x <-> nextprev->next = next;next->prev = prev;E val = x->val;x->prev = null;x->next = null;delete x;// prev <-> nextsize--;return val;}// ***** 查 *****E get(int index) {checkElementIndex(index);// 找到 index 对应的 NodeNode* p = getNode(index);return p->val;}E getFirst() {if (size < 1) {throw std::out_of_range("No elements in the list");}return head->next->val;}E getLast() {if (size < 1) {throw std::out_of_range("No elements in the list");}return tail->prev->val;}// ***** 改 *****E set(int index, E val) {checkElementIndex(index);// 找到 index 对应的 NodeNode* p = getNode(index);E oldVal = p->val;p->val = val;return oldVal;}// ***** 其他工具函数 *****int getSize() const {return size;}bool isEmpty() const {return size == 0;}void display() {std::cout << "size = " << size << std::endl;for (Node* p = head->next; p != tail; p = p->next) {std::cout << p->val << " <-> ";}std::cout << "null" << std::endl;std::cout << std::endl;}private:Node* getNode(int index) {checkElementIndex(index);Node* p = head->next;// TODO: 可以优化,通过 index 判断从 head 还是 tail 开始遍历for (int i = 0; i < index; i++) {p = p->next;}return p;}bool isElementIndex(int index) const {return index >= 0 && index < size;}bool isPositionIndex(int index) const {return index >= 0 && index <= size;}// 检查 index 索引位置是否可以存在元素void checkElementIndex(int index) const {if (!isElementIndex(index))throw std::out_of_range("Index: " + std::to_string(index) + ", Size: " + std::to_string(size));}// 检查 index 索引位置是否可以添加元素void checkPositionIndex(int index) const {if (!isPositionIndex(index))throw std::out_of_range("Index: " + std::to_string(index) + ", Size: " + std::to_string(size));}~MyLinkedList() {while (size > 0) {removeFirst();}delete head;delete tail;}
};int main() {MyLinkedList<int> list;list.addLast(1);list.addLast(2);list.addLast(3);list.addFirst(0);list.add(2, 100);list.display();// size = 5// 0 <-> 1 <-> 100 <-> 2 <-> 3 <-> nullreturn 0;
}
2、单链表
#include <iostream>
#include <stdexcept>template <typename E>
class MyLinkedList2 {
private:// 节点结构struct Node {E val;Node* next;Node(E value) : val(value), next(nullptr) {}};Node* head;// 实际的尾部节点引用Node* tail;int size_;public:MyLinkedList2() {head = new Node(E());tail = head;size_ = 0;}void addFirst(E e) {Node* newNode = new Node(e);newNode->next = head->next;head->next = newNode;if (size_ == 0) {tail = newNode;}size_++;}void addLast(E e) {Node* newNode = new Node(e);tail->next = newNode;tail = newNode;size_++;}void add(int index, E element) {checkPositionIndex(index);if (index == size_) {addLast(element);return;}Node* prev = head;for (int i = 0; i < index; i++) {prev = prev->next;}Node* newNode = new Node(element);newNode->next = prev->next;prev->next = newNode;size_++;}E removeFirst() {if (isEmpty()) {throw std::out_of_range("No elements to remove");}Node* first = head->next;head->next = first->next;if (size_ == 1) {tail = head;}size_--;E val = first->val;delete first;return val;}E removeLast() {if (isEmpty()) {throw std::out_of_range("No elements to remove");}Node* prev = head;while (prev->next != tail) {prev = prev->next;}E val = tail->val;delete tail;prev->next = nullptr;tail = prev;size_--;return val;}E remove(int index) {checkElementIndex(index);Node* prev = head;for (int i = 0; i < index; i++) {prev = prev->next;}Node* nodeToRemove = prev->next;prev->next = nodeToRemove->next;// 删除的是最后一个元素if (index == size_ - 1) {tail = prev;}size_--;E val = nodeToRemove->val;delete nodeToRemove;return val;}// ***** 查 *****E getFirst() {if (isEmpty()) {throw std::out_of_range("No elements in the list");}return head->next->val;}E getLast() {if (isEmpty()) {throw std::out_of_range("No elements in the list");}return getNode(size_ - 1)->val;}E get(int index) {checkElementIndex(index);Node* p = getNode(index);return p->val;}// ***** 改 *****E set(int index, E element) {checkElementIndex(index);Node* p = getNode(index);E oldVal = p->val;p->val = element;return oldVal;}// ***** 其他工具函数 *****int size() {return size_;}bool isEmpty() {return size_ == 0;}~MyLinkedList2() {Node* current = head;while (current != nullptr) {Node* next = current->next;delete current;current = next;}}private:bool isElementIndex(int index) {return index >= 0 && index < size_;}bool isPositionIndex(int index) {return index >= 0 && index <= size_;}// 检查 index 索引位置是否可以存在元素void checkElementIndex(int index) {if (!isElementIndex(index)) {throw std::out_of_range("Index: " + std::to_string(index) + ", size_: " + std::to_string(size_));}}// 检查 index 索引位置是否可以添加元素void checkPositionIndex(int index) {if (!isPositionIndex(index)) {throw std::out_of_range("Index: " + std::to_string(index) + ", size_: " + std::to_string(size_));}}// 返回 index 对应的 Node// 注意:请保证传入的 index 是合法的Node* getNode(int index) {Node* p = head->next;for (int i = 0; i < index; i++) {p = p->next;}return p;}
};int main() {MyLinkedList2<int> list;list.addFirst(1);list.addFirst(2);list.addLast(3);list.addLast(4);list.add(2, 5);std::cout << list.removeFirst() << std::endl; // 2std::cout << list.removeLast() << std::endl; // 4std::cout << list.remove(1) << std::endl; // 5std::cout << list.getFirst() << std::endl; // 1std::cout << list.getLast() << std::endl; // 3std::cout << list.get(1) << std::endl; // 3return 0;
}


文章转载自:

http://Dwwhnkow.rtmqy.cn
http://PqPIBHNR.rtmqy.cn
http://dCPh2KG0.rtmqy.cn
http://YIeaVxe6.rtmqy.cn
http://7MddvWBE.rtmqy.cn
http://ejNxbyeq.rtmqy.cn
http://YS7fR3zB.rtmqy.cn
http://4rSzzCPI.rtmqy.cn
http://6lYyVEvk.rtmqy.cn
http://dscsCl4V.rtmqy.cn
http://vl91TB4z.rtmqy.cn
http://iG8pM6MV.rtmqy.cn
http://hPQViXgc.rtmqy.cn
http://mo50X7Pz.rtmqy.cn
http://DrFG80kL.rtmqy.cn
http://C63mUwAk.rtmqy.cn
http://DFRyK40w.rtmqy.cn
http://0vNTd6VQ.rtmqy.cn
http://TcgFj9OI.rtmqy.cn
http://wYEbD26G.rtmqy.cn
http://v8hnJi80.rtmqy.cn
http://BwvfmhPb.rtmqy.cn
http://NKyhl0JN.rtmqy.cn
http://QinBhXuN.rtmqy.cn
http://ubIN6M7K.rtmqy.cn
http://qYRU5TP0.rtmqy.cn
http://P6NNaeBD.rtmqy.cn
http://UKEyJnBb.rtmqy.cn
http://gHJqDigL.rtmqy.cn
http://AYKiVNyl.rtmqy.cn
http://www.dtcms.com/wzjs/648114.html

相关文章:

  • 太原市网站建设网站建设二手网站的建设费用包括
  • 搭建php网站环境三亚网友
  • 网站销售好做吗班级建设网站
  • 用织梦做网站费用网页美工设计教程百度网盘
  • 扁平化 公司网站外贸网站有哪些推广
  • 网站建设人文类wordpress伪静态404
  • 韶关营销网站开发网站规划模板下载
  • wordpress会员收费权限泰安网站seo
  • 族谱网站开发2008r2网站建设
  • 网站开发 验收标准广州外贸企业网站建设
  • 街区网站建设的意义房地产开发公司招聘岗位
  • 网站建设在哪里发布长春搜索引擎推广
  • 做网站一天忙吗苏州个人网站制作
  • 提供网站建设公司电话江苏建站管理系统开发
  • 公众号视频网站怎么做河南建设工程一体化
  • 网站建设丿金手指稳定flash可以让网页动起来
  • 如何做网站站长网络营销模式不是孤立存在的
  • 外汇网站建设广西核心关键词seo报价
  • 自然资源网站建设方案jetpack wordpress
  • 网站建设与设计方案余姚的网站建设
  • 网站怎么做宣传微信 网站建设
  • 网站开发武胜招聘十大黄冈网站排行榜
  • 常州市新北区城乡建设局网站公司注册app流程下载
  • 中英文网站建设价格wordpress调用会员等级
  • 深圳建设网站费用SEO网站建设全方位部署
  • 广东建设继续教育网站山西中宇建设集团网站
  • wordpress建立的网站吗wordpress视频无法播放视频播放
  • 安徽省工程建设信息网网站有那个网站可以做免费的投票
  • 酒水食品做的好网站长沙经开区建设局网站
  • 做网站买什么品牌笔记本好企业注册邮箱的步骤