打卡一小时第二十九、三十、三十一天

发布时间 2023-05-22 21:22:19作者: 伐木工熊大

一.问题描述

请使用模板参数设计实现单向链表模板类LinkList,应能根据需求构建相应类型数据结点的单向链表结构,main(void)完成对其的测试。

(1)设计实现结点模板类Node,结点的数据域应能各种类型数据;其中成员函数getData(void)的作用是获取结点的数据域。构造函数输出信息“Node Constructor run”,拷贝构造函数输出信息“Node CopyConstructor run”,析构函数输出信息“Node Destructor run”
(2)在结点模板类Node的支持下设计实现结点单向链表模板类LinkList,其中:
①LinkList类的数据包括结点链表的头结点headNode和游标position(游标用于表示当前操作位置)  
②有参构造函数实现由数组构建链表的功能,构造函数输出信息“LinkList Constructor run”;拷贝构造函数输出信息“LinkList CopyConstructor run”,析构函数输出信息“LinkList Destructor run”
③设计实现成员函数insertNode(n),其功能为在游标位置后插入一个同类型结点n。
④设计实现成员函数searchNode(value),其功能为在链表中查找数据域等于value的结点,若查找成功的同时修改游标位置。
⑤设计实现成员函数getSize(),其功能为返回链表中的元素个数。
⑥设计实现成员函数next(),其功能为使游标移动到下一个结点。
⑦设计实现成员函数currNode()const,其功能为返回当前结点。
⑧设计实现成员函数delNode(),其功能为移除当前结点。
⑨设计实现成员函数show(),其功能为输出链表。




#include <iostream>
using namespace std;

/*请在这里填写答案*/

int main()
{
    int i,a[5]= {0,1,2,3,4};
    for(i=0;i<5;i++)
        scanf("%d",&a[i]);
    LinkList<int> l1(a,5),l2(l1);
    cout<<l2.getSize()<<endl;
    l1.show();
    if (l2.searchNode(2))
        cout<<"Found:"<<l2.currNode().getData()<<endl;
    else
        cout<<"Not Found"<<endl;
    l2.delNode();
    Node <int> *p1=new Node<int>(11);
    l2.insertNode(*p1);
    l2.show();
    return 0;
}

 

二.设计思路

注意节点的连接

三.代码实现

#include <iostream>
using namespace std;
template <typename T>
class Node {
    T data;
    Node<T>* next;
public:
    Node(T data) : data(data), next(nullptr)
    {
        cout << "Node Constructor run" << endl;
    }

    Node(const Node<T>& p) : data(p.data), next(p.next)
    {
        cout << "Node CopyConstructor run" << endl;
    }

    ~Node()
    {
        cout << "Node Destructor run" << endl;
    }

    T getData() { return data; }
    Node<T>* getNext() { return next; }
    void setNext(Node<T>* next) { this->next = next; }
};
template <typename T>
class LinkList
{
    Node<T>* headNode;
    Node<T>* position;
public:
    LinkList() : headNode(new Node<T>(T())), position(headNode) //创建头节点
    {
        cout << "LinkList Constructor run" << endl;
    }

    LinkList(T data[], int length) : headNode(new Node<T>(T())), position(headNode)
    {
        Node<T>* Node1 = headNode;//Node指向头节点
        for (int i = 0; i < length; ++i) {
            Node1->setNext(new Node<T>(data[i]));//创建一个新的节点作为下一个节点,并且设置下一个节点的数据域
            Node1 = Node1->getNext();//Node指向下一节点
        }
        cout << "LinkList Constructor run" << endl;
    }

    LinkList(const LinkList<T>& p) : headNode(new Node<T>(T())), position(headNode)
    {
        Node<T>* Node1 = p.headNode->getNext();//Node指向形参所指的链表的头节点
        while (Node1 != nullptr) //当链表的节点的指针域非空时进行循环
        {
            position->setNext(new Node<T>(Node1->getData()));//从新创建的链表的头节点的下一节点开始按照原链表的节点的值开始构造
            Node1 = Node1->getNext();//创建完后指向下一节点
            position = position->getNext();
        }
        position = headNode->getNext();
        cout << "LinkList CopyConstructor run" << endl;
    }

    ~LinkList() {
        Node<T>* Node1 = headNode;
        headNode = headNode->getNext();
        position = headNode;
        while (position != nullptr)
        {
            headNode = headNode->getNext();//先依次指向需要删除的节点,断链后删除
            delete position;
            position = headNode;
        }
        cout << "LinkList Destructor run" << endl;
        delete Node1;
    }

    void insertNode(Node<T>& n)
    {
        n.setNext(position->getNext());//设置节点的值
        position->setNext(&n);
    }

    bool searchNode(T value) //查找节点
    {
        position = headNode->getNext();
        while (position != nullptr)
        {
            if (position->getData() == value)
            {               //position指向查找到的节点
                return true;
            }
            position = position->getNext();
        }
        return false;
    }

    int getSize() const //获取链表长度
    {
        int size = 0;
        Node<T>* Node1 = headNode->getNext();
        while (Node1 != nullptr)
        {
            ++size;
            Node1 = Node1->getNext();
        }
        return size;
    }

    bool next() //指向下一节点,成功返回true,失败返回false
    {
        if (position->getNext() != nullptr)
        {
            position = position->getNext();
            return true;
        }
        return false;
    }

    Node<T>& currNode() const //返回当前节点
    {
        return *position;
    }

    void delNode() //删除节点
    {
        if (position == headNode) //保证不是删除头节点
        {
            return;
        }
        Node<T>* Node1 = headNode;
        while (Node1->getNext() != position) //找到要删除的节点的前一个节点
        {
            Node1 = Node1->getNext();
        }
        Node1->setNext(position->getNext());//找到要删去的节点的前一个节点,使其指向要删除节点的下一个节点,然后删去目标节点再讲position置回
        position = Node1;
    }

    void show() const
    {
        Node<T>* Node1 = headNode->getNext();
        cout << "[";
        while (Node1 != nullptr)
        {
            cout << Node1->getData();
            if (Node1->getNext() != nullptr)
            {
                cout << "][";
            }
            Node1 = Node1->getNext();
        }
        cout << "]" << endl;
    }

};
int main()
{
    int i, a[5] = { 0,1,2,3,4 };
    for (i = 0; i < 5; i++)
        scanf_s("%d", &a[i]);
    LinkList<int> l1(a, 5), l2(l1);
    cout << l2.getSize() << endl;
    l1.show();
    if (l2.searchNode(2))
        cout << "Found:" << l2.currNode().getData() << endl;
    else
        cout << "Not Found" << endl;
    l2.delNode();
    Node <int>* p1 = new Node<int>(11);
    l2.insertNode(*p1);
    l2.show();
    return 0;
}