List(C++模版实现的带哨兵的双向链表)

//
// Created by 许加权 on 2021/7/10.
//#ifndef C11LEARN_LIST_H
#define C11LEARN_LIST_H
template<typename T>
class List
{protected:class Node{public:Node *pre;Node *next;T key;Node(){}Node(const T key):key(key){}};private:Node* Nil;int size;
public:List();virtual ~List();List(const List<T> & list);const List<T> & operator=(const List<T> & list);const List<T> & operator+(const List<T> & list);const List<T> & operator-(const List<T> & list);List<T> merge(const List<T> & list);List<T> except(const List<T> & list);List<T> intersect(const List<T> & list);void add(const T key);void insert(const T key,int position);bool remove(const T key);bool remove_all(const T key);bool remove_at(int index);bool contain(const T &key);T operator[](int index) const;T & operator[] (int index);bool empty();void clear();int length() const;int length();void sort(bool ascending = true);void sort(void(*f)(T *array,int length));const List<T> & distinct();
private:Node* search(const T & key);
//    Node* search01(const T & key);Node* get(int index)const;void add(Node* node);bool remove(Node* node);void quick_sort(T*array,int start,int end,bool ascending = true);int partition(T*array,int start,int end,bool ascending);
};template<typename T>
List<T>::List()
{Nil = new Node();Nil->next = Nil;Nil->pre = Nil;size = 0;
}
template<typename T>
List<T>::~List(){clear();delete Nil;
}
template<typename T>
List<T>::List(const List<T> & list)
{Nil = new Node();Nil->next = Nil;Nil->pre = Nil;size = 0;Node * current = list.Nil->next;while (current != list.Nil){add(current->key);current = current->next;}
}
template<typename T>
const List<T>& List<T>::operator=(const List<T> & list){if(&list == this)return *this;clear();Node * current = list.Nil->next;while (current != list.Nil){add(current->key);current = current->next;}return *this;
}
template<typename T>
List<T> List<T>::merge(const List<T> & list)
{List<T> temp(*this);temp.distinct();Node* current = list.Nil->next;while (current!=list.Nil){if(!temp.contain(current->key)){temp.add(current->key);}current = current->next;}return temp;
}
template<typename T>
List<T> List<T>::except(const List<T> & list){List<T> temp(*this);temp.distinct();Node* current = list.Nil->next;while (current!=list.Nil){if(temp.contain(current->key)){temp.remove(current->key);}current = current->next;}return temp;
}
template<typename T>
List<T> List<T>::intersect(const List<T> & list){List<T> temp;Node* current = list.Nil->next;while (current!=list.Nil){if(contain(current->key)){temp.add(current->key);}current = current->next;}temp.distinct();return temp;
}
template<typename T>
const List<T> & List<T>::distinct(){if(size == 0) return *this;T* array = new T[size];int index = 0;Node* current = Nil->next;while (current!=Nil){array[index] = current->key;current =current->next;index++;}quick_sort(array,0,size-1);T current_key = array[0];for (int i = 1; i < size; ++i) {if(current_key == array[i]){remove(current_key);}else{current_key = array[i];}}delete[] array;return *this;
}
template<typename T>
void List<T>::add(const T key)
{Node* node = new Node(key);size++;add(node);
}
template<typename T>
void List<T>::add(Node* node){if(Nil->next == Nil){Nil->pre = node;Nil->next = node;node->pre = Nil;node->next = Nil;}else{Nil->pre->next = node;node->pre = Nil->pre;node->next = Nil;Nil->pre = node;}
}
template<typename T>
void List<T>::insert(const T key,int position)
{if(position<0 || position>size)throw "out of bound";if(position == size || size == 0){add(key);}else{Node* node = new Node(key);Node* current = get(position);current->pre->next = node;node->pre = current->pre;node->next = current;current->pre = node;size++;if(position == 0){Nil->next = node;}}
}
template<typename T>
bool List<T>::remove(const T key){Node *result =  search(key);if(result!= Nil){remove(result);return true;}return false;
}
template<typename T>
bool List<T>::contain(const T& key){return search(key) != Nil;
}
template<typename T>
bool List<T>::empty(){return Nil->next == Nil;
}
template<typename T>
typename List<T>::Node* List<T>::search(const T &key) {Node * current = Nil->next;while (current != Nil && current->key!=key){current = current->next;}return current;
}
//template<typename T>
//typename List<T>::Node* List<T>::search01(const T &key) {//    Nil->key = key;
//    Node * current = Nil->next;
//    while (current->key!=key)
//    {//        current = current->next;
//    }
//    return current;
//}
template<typename T>
bool List<T>::remove(Node* node){if(empty()) return false;node->pre->next = node->next;node->next->pre = node->pre;size --;delete node;return true;
}
template<typename T>
void List<T>::clear(){Node* current = Nil->next;while (current!= Nil){Node * temp = current;current = current->next;delete temp;}Nil->next = Nil;Nil->pre = Nil;size = 0;
}
template<typename T>
int List<T>::length() const  {return size;
}
template<typename T>
int List<T>::length()  {return size;
}
template<typename T>
T List<T>::operator[](int index) const{return get(index)->key;
}
template<typename T>
T & List<T>::operator[] (int index){return get(index)->key;
}
template<typename T>
typename List<T>::Node* List<T>::get(int index) const{if(index>=size || index < 0) throw "Index out of bounds";Node * current;if(index>=size/2){index = size - index - 1;current = Nil->pre;while (index-->0){current = current->pre;}}else{current = Nil->next;while (index-->0){current = current->next;}}return current;
}
template<typename T>
bool List<T>::remove_at(int index){if(index>=size) return false;return remove(get(index));
}
template<typename T>
void List<T>::quick_sort(T*array,int start,int end,bool ascending){if(start<end){int k = partition(array,start,end,ascending);quick_sort(array,start,k-1,ascending);quick_sort(array,k+1,end,ascending);}
}
template<typename T>
int List<T>::partition(T*array,int start,int end,bool ascending){T key = array[end];int p = start - 1;T temp;for (int i = start; i < end; ++i) {if((array[i] <= key && ascending) ||(array[i] >= key && !ascending) ){p++;temp = array[p];array[p] = array[i];array[i] = temp;}}array[end] = array[p+1];array[p+1] = key;return p+1;
}
template<typename T>
void List<T>::sort(bool ascending){if(size == 0) return;T*array = new T[size];Node* current = Nil->next;int index = 0;while (current!=Nil){array[index] = current->key;current = current->next;index++;}quick_sort(array,0,size - 1,ascending);int length = size;clear();for (int i = 0; i < length; ++i) {add(array[i]);}delete[] array;
}
template<typename T>
void List<T>::sort(void(*f)(T *array,int length)){if(size == 0) return;T*array = new T[size];Node* current = Nil->next;int index = 0;while (current!=Nil){array[index] = current->key;current = current->next;index++;}f(array,size);int length = size;clear();for (int i = 0; i < length; ++i) {add(array[i]);}delete[] array;
}
template<typename T>
const List<T> & List<T>::operator+(const List<T> & list){Node* current =  list.Nil->next;while (current!=list.Nil){add(current->key);current = current->next;}return *this;
}
template<typename T>
const List<T> & List<T>::operator-(const List<T> & list){Node* current =  list.Nil->next;while (current!=list.Nil){remove_all(current->key);current = current->next;}return *this;
}
template<typename T>
bool List<T>::remove_all(const T key){Node* current = Nil->next;bool success = false;while (current!=Nil){if(current->key == key){success = true;Node* node = current;current = current->next;node->pre->next = node->next;node->next->pre = node->pre;size --;delete node;}else{current = current->next;}}return success;
}
#endif //C11LEARN_LIST_H

List(C++模版实现的带哨兵的双向链表)相关推荐

  1. 带哨兵节点的链_【算法导论】10.2不带哨兵节点和带哨兵节点的双向链表

    不带哨兵节点的双向链表即一般的双向链表,有一个头指针指向第一个节点,每个节点有key值和两个指针next和pre,分别指向前后相邻的节点,头结点的pre=NULL,尾节点的next=NULL,比较明了 ...

  2. java导出excel带图片_JAVA的poi实现模版导出excel(带图片).doc

    JAVA的poi实现模版导出excel(带图片) 下面是本人使用java的poi实现使用模板到处excel,内容包含图片,使用两种不同的方式实现其到处excel.但是使用jxl实现到处excel只能到 ...

  3. 带哨兵的环形双向链表

    /**带哨兵的环形双向链表*具有对链表的插入 浏览 删除的功能*Author: StoryMonster*Last Change Date: 2016/6/22*/#include <iostr ...

  4. 带哨兵的冒泡排序_冒泡排序的优化以及快排过程及优化

    冒泡排序的优化: 1.加入哨兵.2.记住每一次交换的最后位置,该位置以后的为有序,不需要改变. 1.快速排序的基本思想: 快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关 ...

  5. 带哨兵节点的链_关于链表中哨兵结点问题的深入剖析

    算法 数据结构 关于链表中哨兵结点问题的深入剖析 最近正在学习UC Berkeley的CS61B这门课,主要是采用Java语言去实现一些数据结构以及运用数据结构去做一些project.这门课不仅告诉你 ...

  6. 带哨兵节点的链_HBA公链 | IPFS:区块链“不可能三角”的可能解

    你知道区块链中的"不可能三角"吗?即区块链无法同时达到可扩展性(Scalability).去中心化(Decentralization)和安全(Security).这三个要素中只能同 ...

  7. 带哨兵节点的链_BNC公链 | IPFS:区块链“不可能三角”的可能解

    你知道区块链中的"不可能三角"吗?即区块链无法同时达到可扩展性(Scalability).去中心化(Decentralization)和安全(Security).这三个要素中只能同 ...

  8. 带哨兵节点的链_Redis 哨兵节点之间相互自动发现机制(自动重写哨兵节点的配置文件)...

    Redis的哨兵机制中,如果是多哨兵模式,哨兵节点之间也是可以相互感知的,各种搜索之后出来的是千篇一律的一个基础配置文件, 在配置当前哨兵节点的配置文件中,并没有配置其他哨兵节点的任何信息. 如下是一 ...

  9. 带哨兵节点的链_第五章:部署带安全认证的3节点哨兵集群

    下面所示是sentinel.conf配置文件 #创建配置文件路径 mkdir /etc/sentinel #创建数据文件路径 mkdir -p /var/sentinel/26379 #拷贝senti ...

最新文章

  1. puppet原理及配置
  2. 【mysql】sql查询速度不变?不同数据量下,查询速度不会变化的问题
  3. Android5.0新特性-Material Design
  4. Ping命令及其协议
  5. 删除ubuntu linux系统,从Windows双启动中卸载Ubuntu Linux
  6. php 双向队列,PHP实现一个双向队列
  7. linux大文件系统管理,Linux 磁盘和文件系统管理
  8. 信息学奥赛一本通(1057:简单计算器)
  9. ps计算机按键.,计算机一级Photoshop视图操作快捷键
  10. 第一章 硬件介绍和环境配置
  11. package.json详解
  12. 大疆aeb连拍_大疆进军运动相机领域,发布OSMO?ACTION,对标GoPro
  13. 数据库系统 图书管理系统 C语言
  14. java 下载文件的文件名乱码_java下载文件名乱码解决方法介绍
  15. teamviewer 远程控制linux,Linux远程控制软件-TeamViewer
  16. 【后缀数组】【线段树】codeforces102028H Can You Solve the Harder Problem?
  17. 海量数据下的舆情分析,该如何搭建?
  18. OOM和JVM最详细介绍
  19. 【松岩早盘视点】2019-9-19
  20. 【CodingNoBorder - 06】无际软工队 - 会议纪要博客列表

热门文章

  1. 地理知识归纳:影响降水的九大因素
  2. toolStripButton调整大小并只显示text
  3. LeetCode之Sum of Two Integers
  4. linux之写C代码出现warning: format not a string literal and no format arguments [-Wformat-security]
  5. php html标签自定义属性,详解H5的自定义属性data-*
  6. 带你见识不一样的世界,这5部豆瓣纪录片不可错过!
  7. “妈,你当年咋看上我爸的?”网友晒爸妈结婚照,笑抽了!
  8. 黑科技轮胎:有能发电的,脑洞简直不要太大...
  9. 5道谷歌面试题:即使是天才也要怀疑自己能力了(附答案)
  10. 朴素贝叶斯--文档分类