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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值