day49、(容器、迭代器、泛型算法)代码实现

本文介绍了一种双向线性链表的数据结构实现,并通过多个测试案例展示了如何使用该链表进行基本操作如插入、删除等。此外,还提供了一个线性查找函数用于在链表中查找指定元素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>

#include <cstring>

#include <stdexcept>

using namespace std;

// 双向线性链表

template<typename T>

class List {

public:

   // 构造、析构、拷贝构造、拷贝赋值

   List (void) :m_head (NULL),

       m_tail (NULL) {}

   ~List (void) {

       clear ();

    }

   List (List const& list) :m_head (NULL),

       m_tail (NULL) {

       for (Node* node = list.m_head;

            node;node = node->m_next)

            push_back (node->m_data);

    }

   List& operator= (List const& list) {

       if (&list != this) {

           List temp = list;  // 拷贝赋值

           swap (m_head,temp.m_head);

           swap (m_tail,temp.m_tail);

       }

       return *this;

    }

   // 获取首元素

   T& front (void) {

       if (empty ())

           throw underflow_error ("链表下溢!");

       return m_head->m_data;

    }

    Tconst& front (void) const {

       return const_cast<List*> (this)->

           front ();

    }

   // 向首部压入

   void push_front (T const& data) {

       m_head = new Node (data,NULL,

           m_head);

       if (m_head->m_next)

           m_head->m_next->m_prev =m_head;

       else

           m_tail = m_head;

    }

   // 从首部弹出

   void pop_front (void) {

       if (empty ())

           throw underflow_error (

                "链表下溢!");

       Node* next = m_head->m_next;

       delete m_head;

       m_head = next;

       if (m_head)

           m_head->m_prev = NULL;

       else

           m_tail = NULL;

    }

   // 获取尾元素

   T& back (void) {

       if (empty ())

           throw underflow_error ("链表下溢!");

       return m_tail->m_data;

    }

    Tconst& back (void) const {

       return const_cast<List*> (this)->

           back ();  

    }

   // 向尾部压入

   void push_back (T const& data) {

       m_tail = new Node (data,m_tail);

       if (m_tail->m_prev)

           m_tail->m_prev->m_next = m_tail;

       else

           m_head = m_tail;

    }

   // 从尾部弹出

   void pop_back (void){

       if (empty ())

           throw underflow_error ("链表下溢!");

       Node* prev = m_tail->m_prev;

       delete m_tail;

       m_tail = prev;

       if (m_tail)

           m_tail->m_next = NULL;

       else

           m_head = NULL;

    }

   // 删除所有匹配元素

   void remove (T const& data) {

       for (Node* node = m_head,*next;

           node;node = node = next) {

           next = node->m_next;

           if (equal (node->m_data,data)) {

                if (node->m_prev)

                node->m_prev->m_next=  // 待删除节点的前指针指向后

                    node->m_next;

                else

                    m_head = node->m_next;

                if (node->m_next)

                node->m_next->m_prev =

                    node->m_prev;

                else

                    m_tail = node->m_prev;

                delete node;

           }

       }

    }

   // 清空

   void clear (void) {

       while (! empty ())

           pop_back ();

    }

   // 判空

   bool empty (void) const {

       return ! m_head && ! m_tail;

    }

   // 大小(元素个数)

   size_t size (void) const {

       size_t nodes = 0;

       for (Node* node = m_head;node;

           node = node->m_next)

           ++nodes;

       return nodes;

    }

   /*

   // 随即访问——(不好)——O(N)复杂度

   T& operator[] (size_t i) {

       for (Node* node = m_head;node;

           node = node->m_next)

           if (! i--)

               return node->m_data;

       throw out_of_range ("下标越界!");

    }

    Tconst& operator[] (size_t i) const {

       return const_cast<List&> (*this) [i];

    }

   */

   

   // 插入输出流

   friend ostream& operator<< (ostream& os,

       List const& list) {

       for (Node* node = list.m_head;node;

           node = node->m_next)

           os << *node;

       return os;

    }

private:

   // 节点

   class Node {

   public:

       // 构造器

       Node (T const& data,

           Node* prev = NULL,

           Node* next = NULL):

           m_data (data),m_prev (prev),

           m_next (next) {}

       // 插入输出流

       friend ostream& operator<< (

           ostream& os,Node const& node) {

           return os << '(' << node.m_data << ')';

        }

       T     m_data; // 数据

       Node* m_prev; // 前指针

       Node* m_next; // 后指针

   };

   // 元素判等的通用版本

   bool equal (T const& a,

       T const& b) const {

       return a == b;

    }

   Node* m_head; // 头指针

   Node* m_tail; // 尾指针

public:

   // 正向顺序(可写)迭代器

   // 正向:增向尾,减向头

   // 顺序:一次迭代一个位置

   // 可写:目标元素可被修改

   // 扮演一个指向元素的指针

   class Iterator {

   public:

       Iterator (Node* head = NULL,

           Node* tail = NULL,

           Node* node = NULL):

           m_head (head),m_tail (tail),

           m_node (node) {}

       bool operator== (Iterator

           const& it) const {

           return m_node == it.m_node;

       }

       bool operator!= (Iterator

           const& it) const {

           return ! (*this == it);

       }

       // 前++

       Iterator& operator++ (void) {

           if (m_node)

                m_node = m_node->m_next;

           else

                m_node = m_head;

           return *this;

       }

       // 后++

       Iterator const operator++ (int) {

            Iterator it = *this;

           ++*this;

           return it;

       }

       // 前减减

       Iterator& operator-- (void) {

           if (m_node)

                m_node = m_node->m_prev;

           else

                m_node = m_tail;

           return *this;

       }

       // 后减减

       Iterator const operator-- (int) {

           Iterator it = *this;

           --*this;

           return it;

       }

       T& operator* (void) const {

           return m_node->m_data;

       }

        T* operator-> (void) const {

           return &**this;

       }

   private:

       Node* m_head;

       Node* m_tail;

       Node* m_node;

       friend class List;

   };

   // 获取起始正向顺序(可写)迭代器

   // 指向首元素

   Iterator begin (void) {

        return Iterator (m_head,m_tail,m_head);

    }

   // 获取终止正向顺序(可写)迭代器

   // 指向尾元素之后

   Iterator end (void) {

       return Iterator (m_head,m_tail); // 第三个元素缺省即空指针

    }

   // 插入

   // 在迭代器pos所指向的元素之前插入data

   // 返回指向新插入元素的迭代器

   Iterator insert (Iterator pos,

       T const& data) {

       if (pos == end ()) {

           push_back (data);

           return Iterator (m_head,m_tail,

                m_tail);

       }

       else {

           Node* node = new Node (data,

                pos.m_node->m_prev,pos.m_node);

           if (node->m_prev)

                node->m_prev->m_next =node;

           else

                m_head = node;

           node->m_next->m_prev = node;

           return Iterator (m_head,m_tail,

                node);

       }

    }

   // 删除

   // 删除迭代器pos所指向的元素

   // 返回被删除元素下一个位置的迭代器

   Iterator erase (Iterator pos) {

       if (pos == end ())

           throw invalid_argument ("无效参数!");

       if (pos.m_node->m_prev)

           pos.m_node->m_prev->m_next =

                pos.m_node->m_next;

       else

           m_head = pos.m_node->m_next;

       if (pos.m_node->m_next)

           pos.m_node->m_next->m_prev =

                pos.m_node->m_prev;

       else

           m_tail = pos.m_node->m_prev;

        Node* next = pos.m_node->m_next;

       delete pos.m_node;

       return Iterator (m_head,m_tail,next);

    }

   // 正向顺序只读迭代器

   // class ConstIterator {};

   // ConstIterator begin (void) const {}

   // ConstIterator end (void) cosnt {}

   // 反向顺序可写迭代器

   // class ReverseIterator {};

   // ReverseIterator rbegin (void) {}

   // ReverseIterator rend (void) {}

   // 反向顺序只读迭代器

   // class ReverseConstIterator {};

   // ReverseConstIterator rbegin (void) const {}

   // ReverseConstIterator rend (void) const {}

};

// 元素判等的特化版本

template<>

bool List<char const*>::equal (charconst* const& a,

   char const* const& b) const {

   return ! strcmp (a,b);

}

// 线性查找

/*

int find (int data[],size_t size,int key) {

   for (int i = 0;i < size;++i)

        if (data[i] == key)

           return i;

   return -1;

}

*/

/*

int* find (int* begin,int* end,int key) {

   int* it;

   for (it = begin;it != end;++it)

       if (*it == key)

           break;

   return it;

}

*/

template<typename IT,typename KEY>

IT find (IT begin,IT end,KEY const key) {

   IT it;

   for (it = begin;it != end;++it)

       if (*it == key)

           break;

   return it;  

}

// 测试用例

void test1 (void) {

   List<int> li;

   li.push_front (30);

   li.push_front (20);

   li.push_front (15);

   cout << li << endl; // 15 20 30

   li.front () -= 5;

   cout << li << endl; // 10 20 30

   List<int> const& cr = li;

// ++cr.front ();

   cout << cr.front () << endl;

   li.pop_front (); // 10

   cout << li << endl; // 20 30

    li.push_back (40);

   li.push_back (50);

   li.push_back (55);

   cout << li << endl; // 20 30 40 50 55

   li.back () += 5;

   cout << li << endl; // 20 30 40 50 60

   List<int> const* cp = &li;

// cp->back ()--;

   cout << cp->back () << endl; // 60

   li.pop_back ();

   cout << li << endl; // 20 30 40 50

   li.push_front (30);

   li.push_front (30);

   li.push_back (30);

   li.push_back (30);

   cout << li << endl; // 30 30 20 30 40 50 30 30

   li.remove (30);

   cout << li << endl; // 20 40 50

   cout << boolalpha << li.empty () << ' '

       << li.size () << endl; // false 3

   li.clear ();

   cout << li.empty () << ' '

       << li.size () << endl; // true 0

}

void test2 (void) {

   List<int> l1;

   l1.push_back (100);

   l1.push_back (200);

   l1.push_back (300);

   l1.push_back (400);

   l1.push_back (500);

   List <int> l2 = l1; // 拷贝构造

   cout << "l1: " << l1 << endl;

   cout << "l2: " << l2 << endl;

   // 验证是否为深拷贝

   l1.pop_front (); // 200 300 400 500

   l2.pop_back (); //  100 200 300400

   cout << "l1: " << l1 << endl;

   cout << "l2: " << l2 << endl;

   l2 = l1; // 拷贝赋值

   cout << "l1: " << l1 << endl;

   cout << "l2: " << l2 << endl;

   l1.push_front (100);

   l2.push_back (600);

   cout << "l1: " << l1 << endl;

   cout << "l2: " << l2 << endl;

}

void test3 (void) {

   

   char ca[][256] = {"北京","上海","北京",

       "天津","北京","重庆","北京"};

   

   /*

   char const* ca[] = {"北京","上海","北京",

       "天津","北京","重庆","北京"};

   */

   List</*string*/char const*> ls;

   for (size_t i = 0;i < sizeof (ca) /

       sizeof (ca[0]);++i)

       ls.push_back (ca[i]);

   cout << ls << endl;

   ls.remove ("北京");

   cout << ls << endl;

}

void test4 (void) {

   List<int> li;

   for (int i = 1;i < 10; ++i)

        li.push_back (i);

   cout << li << endl;

   /*

   // O(N^2)

   size_t size = li.size ();

   for (size_t i = 0;i < size;++i)

       li[i] *= li[i];

   */

   // O(N)

   for (List<int>::Iterator it = li.begin ();

       it != li.end (); ++it)

        *it *= *it;

   cout << li << endl;

}

void test5 (void) {

   List<int> li;

   li.push_front (90);

   li.push_front (50);

   li.push_front (10);

   cout << li << endl; // 10 50 90

   List<int>::Iterator pos = li.begin ();

   li.insert (li.insert(li.insert (++pos,40),30),20);

   cout << li << endl;

   pos = li.end ();

   li.insert (li.insert(li.insert(--pos,80),70),60);

   cout << li << endl; // 10 20 30 40 50 60 70 80 90

   pos = li.begin ();

   li.erase (li.erase (li.erase (++++++pos)));

   cout << li << endl; // 10 20 30  70 80 90

 

}

void test6 (void) {

   int ai[] = {13,19,21,17,33};

   int* pi = find (&ai[0],&ai[5],21);

   if (pi == &ai[5])

       cout << "没找到" << endl;

   else

       cout << "找到:" << *pi << endl;

   List<string> ls;

   ls.push_back ("济南");

   ls.push_back ("菏泽");

   ls.push_back ("临沂");

   ls.push_back ("青岛");

   ls.push_back ("淄博");

   List<string>::Iterator it = find (

       ls.begin (),ls.end (),"临沂");

   if (it == ls.end ())

       cout << "没找到" << endl;

   else

       cout << "找到:" << *it << endl;

}

// 进程入口

int main(void)

{

// test1 ();

// test2 ();

// test3 ();

// test4 ();

// test5 ();

   test6 ();

   return 0;

}

Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业),个人经导师指导并认可通过的高分设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做大作业、毕业设计的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Python实现的CNN卷积神经网络手写数字识别项目代码+代码注释和数据集(毕业设计&期末大作业)Pyth
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值