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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/309033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java实现栈(顺序栈,链栈)

顺序栈&#xff1a; package SeqStack;public class Stack {private int top;private int base[];private int stackSize;public Stack(){stackSize 100;base new int[stackSize];top -1;}public Stack(int n){stackSize n;base new int[stackSize];top -1;}public bool…

全宇宙首本 VS Code 中文书,来了!

大家好&#xff01;我是韩骏&#xff0c;VS Code 中文社区创始人&#xff0c;VS Code 的代码贡献者。2013 年&#xff0c;毕业于上海交通大学软件学院&#xff0c;现在是微软开发平台事业部的软件工程师。写过 20 多款 VS Code 插件&#xff0c;其中最热门的 Code Runner 插件有…

用一个单链表L实现一个栈(算法导论第十章10.2-2题)

用一个单链表L实现一个栈&#xff08;算法导论第十章10.2-2题&#xff09; template<typename T> class HalfNode { public:T key;HalfNode* next; public:HalfNode(){next nullptr;};HalfNode(const T key):key(key){next nullptr;}; }; template<typename T> …

Java实现队列(循环队列,链队列)

循环队列: package SeqQueue;public class Queue {private int data[];private int queueSize;private int front,rear;public Queue(){data new int[100];queueSize 100;front rear 0;}public Queue(int n){queueSize n;data new int[queueSize];front rear 0;}publi…

C# 从1到Core--委托与事件

委托与事件在C#1.0的时候就有了&#xff0c;随着C#版本的不断更新&#xff0c;有些写法和功能也在不断改变。本文温故一下这些改变&#xff0c;以及在NET Core中关于事件的一点改变。一、C#1.0 从委托开始1. 基本方式什么是委托&#xff0c;就不说概念了&#xff0c;用例子说话…

用一个单链表L实现一个队列(算法导论第十章10.2-3)

用一个单链表L实现一个队列&#xff08;算法导论第十章10.2-3) template<typename T> class HalfNode { public:T key;HalfNode* next; public:HalfNode(){next nullptr;};HalfNode(const T key):key(key){next nullptr;}; }; template<typename T> class Singl…

开源导入导出库Magicodes.IE 多sheet导入教程

多Sheet导入教程说明本教程主要说明如何使用Magicodes.IE.Excel完成多个Sheet数据的Excel导入。要点多个相同格式的Sheet数据导入多个不同格式的Sheet数据导入主要步骤1. 多个相同格式的Sheet数据导入1.1 创建导入Sheet的Dto主要代码如下所示&#xff1a;学生数据Dto/// <su…

Java实现二叉树

二叉树: package Tree;import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; import java.util.Stack;public class BinTree {private class TreeNode{int data;TreeNode left;TreeNode right;public TreeNode(){data 0;left null;right nul…

解决 Azure AD 在 Azure Front Door 下登录失败的问题

点击上方关注“汪宇杰博客” ^_^导语最近我给博客系统加上了 Azure Front Door&#xff0c;集齐了12项 Azure 服务打算召唤神龙。没想到刚上线&#xff0c;Azure AD 的单点登录就爆了。OIDC 跳转错误当我尝试登录博客后台的时候&#xff0c;OIDC的跳转URL突然变成了 https://ed…

二叉搜索树的插入与删除(C语言)

代码如下: BinTree Insert( BinTree BST, ElementType X ) {if( !BST ){ /* 若原树为空&#xff0c;生成并返回一个结点的二叉搜索树 */BST (BinTree)malloc(sizeof(struct TNode));BST->Data X;BST->Left BST->Right NULL;}else { /* 开始找要插入元素的位置 */…

算法导论10-2.4题

算法导论10-2.4题 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; }其他全部代码链接

Linux中作业控制命令

开门见山&#xff0c;最近.NET劝退师要在linux上写些长时间运行的脚本&#xff0c;获取Azure BlobStorage存储的数据。记录一下Linux中后台执行作业的命令。Linux作业作业(Job)是shell管理的进程(每个job都有一个关联的PID)&#xff0c;每个作业会被分配一个线性job ID。有两种…

使用单项循环链表实现字典操作(算法导论第十章10.2-5题)

使用单项循环链表实现字典操作(算法导论第十章10.2-5题) template<typename T> void insert(SingleCycleL<T> & l,T key) {HalfNode<T> * t new HalfNode<T>(key);t->next l.Nil->next;l.Nil->next t; } template<typename T> …

《Unit Testing》2.1 经典学派如何做测试隔离

经典学派如何解决隔离问题首先&#xff0c;再回顾一下单元测试的三个重要特性&#xff1a;验证一小段代码&#xff08;或者叫一个单元&#xff09;执行速度快使用隔离的方式进行针对第一个特性就会引出一个问题&#xff1a;多小的一段代码才足够小&#xff1f;如果你采用针对每…

AVL树的旋转与插入(C语言)

代码如下: typedef struct AVLNode *Position; typedef Position AVLTree; /* AVL树类型 */ struct AVLNode{ElementType Data; /* 结点数据 */AVLTree Left; /* 指向左子树 */AVLTree Right; /* 指向右子树 */int Height; /* 树高 */ };int Max ( int a, int b …

单项循环链表

单项循环链表 // // Created by 许加权 on 2021/7/12. //#ifndef C11LEARN_SINGLECYCLELINK_H #define C11LEARN_SINGLECYCLELINK_H #include "chapter10.h" template<typename T> class SingleCycleL { public:HalfNode<T> *Nil; public:SingleCycleL(…

Hacker News热文:请停止学习框架,学习领域驱动设计(DDD)(获500个点赞)

在 Hacker News 上获得接近 500 个点赞的一篇名为《停止学习框架》的文章称&#xff1a;我们是程序员&#xff0c;每天都在了解最新的技术&#xff0c;每天都在学习编程语言、框架和库&#xff0c;因为我们知道的现代编程工具越多越好&#xff0c;对吧&#xff1f;不停地追随 A…

堆的定义与操作(C语言)

代码如下: typedef struct HNode *Heap; /* 堆的类型定义 */ struct HNode {ElementType *Data; /* 存储元素的数组 */int Size; /* 堆中当前元素个数 */int Capacity; /* 堆的最大容量 */ }; typedef Heap MaxHeap; /* 最大堆 */ typedef Heap MinHeap; /* 最小…

Θ(n)反转单链表(算法导论第三版第十章10.2-7)

Θ(n)反转单链表 (算法导论第三版第十章10.2-7) template<typename T> void reverses(Single_L<T> &l) {if(l.head nullptr || l.head l.tail) return;HalfNode<T> * tail l.head;HalfNode<T>*pre l.head;HalfNode<T>*current pre-&g…

C#跨平台开源项目实战(WPF/Android/IOS/Blazor)

个人介绍由于本人从业WPF开发, 考虑到国内的WPF开发环境并不是很好, 资源少、项目案例少, 所以导致很多初学者就已经断了念头。所以我作为WPF的从业者, 就在2019年,开始了发布自己的WPF相关的免费教学视频。发布开源的项目实践, WPF的基础视频、项目实践视频, 包括WPF UI设计视…