• 链表(模板)类


    链表类依赖于cmath头文件,使用ListNode,List四个文件实现:

    ListNode.h:

     1 /*********************************************
     2 ListNode.h
     3 链表节点(模板)类 ListNode
     4 T 节点数据
     5 pred 前节点指针
     6 succ 后节点指针
     7 ListNode / ListNode(T, T*, T*) 构造
     8 InsertPred(T) 前插入节点
     9 InsertSucc(T) 后插入节点
    10 
    11  * Created by QSY 2020.10.11
    12  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
    13  * Department Of Automation, Tsinghua University
    14  * Copyright (c) 2020. All rights reserved.
    15 **********************************************/
    16 #pragma once
    17 
    18 typedef int Rank; //
    19 #define Posi(T) ListNode<T>* //列表节点指针
    20 
    21 template<typename T> 
    22 struct ListNode
    23 {
    24     T data;//节点数据
    25     Posi(T) pred;//前驱节点引用
    26     Posi(T) succ;//后继节点引用
    27     ListNode() {};//空构造
    28     ListNode(T e, Posi(T) p = nullptr, Posi(T) s = nullptr)
    29         :date(e), pred(p), succ(s) {};
    30     Posi(T) InsertPred(T const& e);//前插入节点
    31     Posi(T) InsertSucc(T const& e);//后插入节点
    32 };

    ListNode.cpp:

     1 /*********************************************
     2 ListNode.cpp
     3 
     4  * Created by QSY 2020.10.11
     5  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
     6  * Department Of Automation, Tsinghua University
     7  * Copyright (c) 2020. All rights reserved.
     8 **********************************************/
     9 
    10 #include "ListNode.h"
    11 
    12 template<typename T>
    13 Posi(T) ListNode<T>::InsertPred(T const& e) {
    14     Posi(T) x = new ListNode(e, pred, this);
    15     pred->succ = x;
    16     this->pred = x;
    17     return x;
    18 }
    19 
    20 template<typename T>
    21 Posi(T) ListNode<T>::InsertSucc(T const& e) {
    22     Posi(T) x = new ListNode(e, this, succ);
    23     succ->pred = x;
    24     this->succ = x;
    25     return x;
    26 }
    View Code

    List.h:

     1 /*********************************************
     2 链表(模板)类 List
     3 本文件绝大多数函数未考虑非法输入情况,调用前请先依据源代码避免非法输入,否则程序的行为将不可预测
     4 
     5  * Created by QSY 2020.10.14
     6  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
     7  * Department Of Automation, Tsinghua University
     8  * Copyright (c) 2020. All rights reserved.
     9 **********************************************/
    10 #pragma once
    11 #include "ListNode.h"
    12 
    13 template<typename T>
    14 class List
    15 {
    16 private:
    17     Rank _size;//链表长度,不计头尾
    18     Posi(T) header;
    19     Posi(T) trailer;
    20     //header first …… last trailer
    21     //  -1     0        n   n + 1
    22 //内部方法
    23     //可以将p后的n个节点拷贝至当前对象
    24     void CopyNodes(Posi(T) p, int n);
    25     //重载swap函数作为内部方法
    26     void swap(T, T);
    27     void swap(Posi(T), Posi(T));
    28 protected:
    29     //初始化整个列表
    30     void init();
    31     //清除整个链表的数据,恢复为混沌初开的状态
    32     void clear();
    33     
    34 public:
    35 //构造函数
    36     List() { init(); };
    37     List(List<T> const& L);//整体复制列表L
    38     List(List<T> const& L, Rank r, int n);//复制L中自第r项起的n项
    39     List(Posi(T) p, int n);//复制列表中自位置p起的n项
    40 //析构函数
    41     ~List();
    42 //
    43     const Rank& const size = _size;
    44     Rank size() const { return _size; }
    45     bool empty() const { return _size <= 0; }
    46 //节点操作接口
    47     //r->data
    48     T& operator[] (Rank r) const;//重载下标操作符,以通过秩直接访问列表节点数据
    49     //r->p
    50     Posi(T) posi(Rank r);//返回r节点的指针
    51     Posi(T) posi(List<T> const& L, Rank r);//返回r节点的指针
    52     //p->r
    53     Rank rank(Posi(T) p);//返回当前指针的秩
    54     //data->p
    55     Posi(T) find(T const& e) const;
    56     
    57     Rank distance(Posi(T) p, Posi(T) q);//p在q前!
    58     Posi(T) first() const;
    59     Posi(T) last() const;
    60     Posi(T) selectMax(Posi(T) p, int n);
    61     
    62 //写入删除接口
    63     Posi(T) InsertFirst(T const& e);
    64     Posi(T) InsertLast(T const& e);
    65     Posi(T) InsertBefore(Posi(T) p, T const& e);
    66     Posi(T) InsertAfter(Posi(T) p, T const& e);
    67     T Remove(Posi(T) p);
    68 //排序接口
    69     void insert_sort();//invalid
    70     void merge_sort();//o(nlogn)
    71     Posi(T) merge_sort(Posi(T) p, int n);
    72     Posi(T) merge(List<T> L, Posi(T) p, int n, Posi(T) q, int m);
    73     void select_sort();//o(n^2)
    74     void radix_sort();//invalid
    75 //转置接口
    76     void reverse();
    77     void reverse(Posi(T) p1, Posi(T) p2);//p1在p2之前
    78     void reverse(Rank r1, Rank r2);
    79 };

    List.cpp:

      1 /*********************************************
      2 List.cpp
      3 
      4  * Created by QSY 2020.10.11
      5  * Shiyuan Qu, qsy19@mails.tsinghua.edu.cn
      6  * Department Of Automation, Tsinghua University
      7  * Copyright (c) 2020. All rights reserved.
      8 **********************************************/
      9 
     10 #include "List.h"
     11 #include <cmath>
     12 
     13 template<typename T>
     14 void List<T>::CopyNodes(Posi(T) p, int n) {
     15     if (!_size) {
     16         init();
     17     }
     18     else {
     19         clear();
     20     }
     21     while (n--) {
     22         InsertLast(p->data);
     23         p = p->succ;
     24     }
     25 }//有改进空间,栈空间占用过多
     26 
     27 template<typename T>
     28 void List<T>::swap(T t1, T t2) {
     29     T tt = t1;
     30     t1 = t2;
     31     t2 = tt;
     32 }
     33 
     34 template<typename T>
     35 void List<T>::swap(Posi(T) p1, Posi(T) p2) {
     36     Posi(T) pt = p1;
     37     p1 = p2;
     38     p2 = pt;
     39 }
     40 
     41 template<typename T>
     42 void List<T>::init() {
     43     header = new ListNode<T>;
     44     trailer = new ListNode<T>;
     45     header->succ = trailer;
     46     header->pred = nullptr;
     47     trailer->succ = nullptr;
     48     trailer->pred = header;
     49     _size = 0;
     50 }
     51 
     52 template<typename T>
     53 void List<T>::clear() {
     54     int oldsize = _size;
     55     while (0 < _size) {
     56         Remove(header->succ);
     57     }
     58 }
     59 
     60 template<typename T>
     61 List<T>::List(List<T> const& L) {
     62     CopyNodes(L.first(), L._size); 
     63 }
     64 
     65 template<typename T>
     66 List<T>::List(List<T> const& L, Rank r, int n) {
     67     Posi(T) p = Pos(L, r);
     68     CopyNodes(p, n);
     69 }
     70 
     71 template<typename T>
     72 List<T>::List(Posi(T) p, int n) {
     73     CopyNodes(p, n);
     74 }
     75 
     76 template<typename T>
     77 List<T>::~List() {
     78     clear();
     79     delete header;
     80     delete trailer;
     81 }
     82 
     83 template <typename T> 
     84 T& List<T>::operator[] (Rank r) const {
     85     return Pos(r)->data;
     86 }
     87 
     88 template<typename T>
     89 Posi(T) List<T>::posi(Rank r) {
     90     if (_size <= r) {
     91         return nullptr;
     92     }//特判,防止请求越界
     93     Posi(T) p = this->first();
     94     while (0 < r--) {
     95         p = p->succ;
     96     }
     97     return p;
     98 }
     99 
    100 template<typename T>
    101 Posi(T) List<T>::posi(List<T> const& L, Rank r) {
    102     if (L.size <= r) {
    103         return nullptr;
    104     }//特判,防止请求越界
    105     Posi(T) p = L.first();
    106     while (0 < r--) {
    107         p = p->succ;
    108     }
    109     return p;
    110 }
    111 
    112 template<typename T>
    113 Rank List<T>::rank(Posi(T) p) {
    114     Rank r = 0;
    115     Posi(T) ptr = trailer->succ;
    116     while (p != ptr) {
    117         ptr = ptr->succ;
    118         ++r;
    119     }
    120     return 0;
    121 }
    122 
    123 template<typename T>
    124 Posi(T) List<T>::find(T const& e)const {
    125     Posi(T) p = trailer->succ;
    126     for (int i = 0; i < _size; ++i) {
    127         if (p->data == T) {
    128             return p;
    129         }
    130         p = p->succ;
    131     }
    132     return nullptr;
    133 }
    134 
    135 template<typename T>
    136 Rank List<T>::distance(Posi(T) p, Posi(T) q) {
    137     Rank r = 0;
    138     while (p != q) {
    139         p = p->succ;
    140         ++r;
    141     }
    142     return r;
    143 }
    144 
    145 template<typename T>
    146 Posi(T) List<T>::first() const {
    147     if (_size) {
    148         return header->succ;
    149     }//特判,防止无长度
    150     return nullptr;
    151 }
    152 
    153 template<typename T>
    154 Posi(T) List<T>::last() const {
    155     if (_size) {
    156         return trailer->pred;
    157     }
    158     return nullptr;
    159 }
    160 
    161 template<typename T>
    162 Posi(T) List<T>::selectMax(Posi(T) p, int n) {
    163     Posi(T) max = p;
    164     for (; 1 < n; n--) {
    165         if (max->data <= p->data) {
    166             max = p;
    167         }
    168         p = p->succ;
    169     }
    170     return max;
    171 }
    172 
    173 template<typename T>
    174 Posi(T) List<T>::InsertFirst(T const& e) {
    175     _size++;
    176     return header->InsertSucc(T);
    177 }
    178 
    179 template<typename T>
    180 Posi(T) List<T>::InsertLast(T const& e) {
    181     _size++;
    182     return trailer->InsertPred(T);
    183 }
    184 
    185 template<typename T>
    186 Posi(T) List<T>::InsertBefore(Posi(T) p, T const& e) {
    187     _size++;
    188     return p->InsertPred(T);
    189 }
    190 
    191 template<typename T>
    192 Posi(T) List<T>::InsertAfter(Posi(T) p, T const& e) {
    193     _size++;
    194     return p->InsertSucc(T);
    195 }
    196 
    197 template<typename T>
    198 T List<T>::Remove(Posi(T) p) {
    199     T e = p->data;//备份数据
    200     //更新指针指向,拆出链表
    201     p->pred->succ = p->succ;
    202     p->succ->pred = p->pred;
    203     delete p;//释放空间
    204     _size--;
    205     return e;
    206 }
    207 
    208 template<typename T>
    209 void List<T>::insert_sort() {
    210     //
    211 }
    212 
    213 template<typename T>
    214 void List<T>::merge_sort() {
    215     merge_sort(first(), _size);
    216 }
    217 
    218 template<typename T>
    219 Posi(T) List<T>::merge_sort(Posi(T) p, int n) {
    220     Posi(T) pp = p->pred;
    221     Posi(T) q = p;
    222     int m = n >> 2;
    223     for (int i = 0; i < m; ++i) {
    224         q = q->succ;
    225     }
    226     merge_sort(p, m);
    227     merge_sort(q, n - m);
    228     merge(this, p, m, q, n - m);
    229     return pp->succ;
    230 }
    231 
    232 template<typename T>
    233 Posi(T) merge(List<T> L, Posi(T) p, int n, Posi(T) q, int m) {
    234     Posi(T) pp = p->pred;
    235     while (0 < m) {//在q未移出区间之前
    236         if ((0 < n) && p->data <= q->data) {//p未移出区间且p的数据更小
    237             p = p->succ;
    238             --n;
    239         }
    240         else {
    241             q = q->succ;
    242             InsertBefore(p, L.Remove(q->pred));
    243             --m;
    244         }
    245     }
    246     return pp->succ;
    247 }
    248 
    249 template<typename T>
    250 void List<T>::select_sort() {
    251     int n = _size;
    252     Posi(T) first = first();
    253     Posi(T) tail = trailer;
    254     while (1 < n) {
    255         Posi(T) max = selectMax(first, n);
    256         InsertBefore(tail, Remove(max);
    257         tail = tail->pred;
    258         --n;
    259     }
    260 }
    261 
    262 template<typename T>
    263 void List<T>::radix_sort() {
    264     //
    265 }
    266 
    267 template<typename T>
    268 void List<T>::reverse() {
    269     if (_size < 2) {
    270         return;
    271     }
    272     Posi(T) p = header; 
    273     Posi(T) q = trailer;
    274     for (int i = 1; i < _size; i += 2) {
    275         p = p->succ;
    276         q = q->pred;
    277         swap(p->data, q->data);
    278     }
    279 }
    280 
    281 template<typename T>
    282 void List<T>::reverse(Posi(T) p1, Posi(T) p2) {
    283     int n = distance(p1, p2) + 1;
    284     for (int i = 1; i < n; i += 2) {
    285         swap(p1->data, p2->data);
    286         p1 = p1->succ;
    287         p2 = p2->pred;
    288     }
    289 }
    290 
    291 template<typename T>
    292 void List<T>::reverse(Rank r1, Rank r2) {
    293     int n = abs(r2 - r1);
    294     if (n < 2) {
    295         return;
    296     }
    297     if (r1 < r2) {
    298         Posi(T) p = posi(r1);
    299         Posi(T) q = posi(r2);
    300     }
    301     else {
    302         Posi(T) q = posi(r1);
    303         Posi(T) p = posi(r2);
    304     }
    305     for (int i = 1; i < n; i += 2) {
    306         swap(p->data, q->data);
    307         p = p->succ;
    308         q = q->pred;
    309     }
    310 }
    View Code

    //2020.10.15更新,暂未测试

  • 相关阅读:
    Python中数据在内存中存储汇总
    python每日一题:爬取一些代理网站获取动态ip
    python每日一题:关于反爬虫措施
    python每日一题:爬虫一些需要登录账号密码的网站
    python每日一题:爬虫某网站图书信息
    【MyBatis】MyBatis CRUD
    【MyBatis】自定义 MyBatis
    【JavaWeb】i18n 国际化
    【JavaWeb】AJAX 请求
    【JavaWeb】JSON 文件
  • 原文地址:https://www.cnblogs.com/Mergus-Squamatus/p/13818195.html
Copyright © 2020-2023  润新知