Vj实验四链表描述线性表一

A

要求:

  1. 封装链表类,链表迭代器类
  2. 链表类需提供操作:在指定位置插入元素,删除指定元素,搜索链表中是否有指定元素,原地逆置链表,输出链表
  3. 不得使用与链表实现相关的STL

描述:

第一行两个整数 N 和 Q。
第二行 N 个整数,作为节点的元素值,创建链表。
接下来 Q 行,执行各个操作,具体格式如下:

  • 插入操作 : 1 idx val,在链表的 idx 位置插入元素 val;
  • 删除操作 : 2 val,删除链表中的 val 元素。若链表中存在多个该元素,仅删除第一个。若该元素不存在,输出 -1
  • 逆置操作 : 3,原地逆置链表;
  • 查询操作 : 4 val,查询链表中的 val 元素,并输出其索引。若链表中存在多个该元素,仅输出第一个的索引。若不存在该元素,输出 -1
  • 输出操作 : 5,使用 链表迭代器 ,输出当前链表索引与元素的异或和:f(chain)=∑i=0n−1​i⊕chain[i],n=len(chain);

样例:

Input

10 10
6863 35084 11427 53377 34937 14116 5000 49692 70281 73704 
4 6863
1 2 44199
5
4 21466
1 6 11483
5
4 34937
5
4 6863
1 10 18635

Output

0
398665
-1
410141
5
410141
0
#include <iostream>

using namespace std;
template <class T>
struct chainNode
{
    // 数据成员
    T element;          // 节点中数据
    chainNode<T> *next; // 节点的指针
    // 方法
    // 构造函数
    chainNode() {}
    chainNode(const T &element) { this->element = element; } //
    chainNode(const T &element, chainNode<T> *next)
    {
        this->element = element;
        this->next = next;
    }
};
template <class T>
class chain
{
public:
    // friend class iterator;
    // chain<T>::iterator;
    // 构造函数,复制构造函数和析构函数
    chain(int initialCapacity = 10);
    chain(const chain<T> &);
    ~chain();
    // 抽象数据类型ADT的方法
    bool empty() const { return listSize == 0; }
    int size() const { return listSize; }
    int indexOf(const T &theElement) const;         // 查询
    int erase(T &theElement);                       // 删除
    void insert(int theIndex, const T &theElement); // 插入
    int output();                                   // 输出
    void zhihuan();                                 // 链表置换
    // 迭代器
    class iterator
    {
    public:
        iterator(chainNode<T> *theNode = NULL) { node = theNode; }
        // 重载引用操作符
        T &operator*() const { return node->element; }
        T &operator->() const { return &node->element; }
        // 迭代器加法操作
        iterator &operator++()
        { // 前加
            node = node->next;
            return *this;
        }
        iterator operator++(int)
        { // 后加
            iterator old = *this;
            node = node->next;
            return old;
        }
        // 相等检验
        bool operator!=(const iterator right) const { return node != right.node; }
        bool operator==(const iterator right) const { return node == right.node; }

    protected:
        chainNode<T> *node;
    };
    iterator begin() { return iterator(firstNode); }
    iterator end() { return iterator(NULL); }

protected:
    void checkIndex(int theIndex) const; //如果索引无效,抛出异常
    chainNode<T> *firstNode;             // 指向链表第一个节点的指针
    int listSize;                        // 线性表的元素个数
};

// 构造函数
template <class T>
chain<T>::chain(int initialCapacity)
{
    //构造函数
    if (initialCapacity < 1)
    {
        cout << "Initial Capacity must > 0";
    }
    firstNode = NULL;
    listSize = 0;
}

// 迭代器

// 复制构造函数
template <class T>
chain<T>::chain(const chain<T> &theList)
{
    // 复制构造函数
    listSize = theList.listSize;
    if (listSize == 0)
    { // 链表为空
        firstNode = NULL;
        return;
    }
    // 链表非空
    chainNode<T> *sourceNode = theList.firstNode;      // 要复制链表theList的节点
    firstNode = new chainNode<T>(sourceNode->element); // 复制链表theList的首元素
    sourceNode = sourceNode->next;
    chainNode<T> *targetNode = firstNode; // 当前链表*this的最后一个节点
    while (sourceNode != NULL)
    {
        // 复制剩余元素
        targetNode->next = new chainNode<T>(sourceNode->element);
        targetNode = targetNode->next;
        sourceNode = sourceNode->next;
    }
    targetNode->next = NULL; // 链表结束
}

// 析构函数
template <class T>
chain<T>::~chain()
{
    // 链表析构函数,删除链表的所有结点
    while (firstNode != NULL)
    {
        // 删除首结点
        chainNode<T> *nextNode = firstNode->next;
        delete firstNode;
        firstNode = nextNode;
    }
}

// // 获得索引为theIndex的元素
// // template<class T>
// // T& chain<T>::get(int theIndex)const{
//     checkIndex(theIndex);
//     // 移动所需要的节点
//     chainNode<T>* currentNode = firstNode;
//     for(int i = 0; i < theIndex; i++){
//         currentNode = currentNode->next;
//     }
//     return currentNode->element;
// }

// 返回首次出现theElement的索引(查询)
template <class T>
int chain<T>::indexOf(const T &theElement) const
{
    // 搜寻链表寻找元素theElement
    chainNode<T> *currentNode = firstNode;
    int index = 0;
    while (currentNode != NULL && currentNode->element != theElement)
    {
        // 移向下一个节点
        currentNode = currentNode->next;
        index++;
    }
    if (currentNode == NULL)
    {
        return -1;
    }
    else
    {
        return index;
    }
}

// 插入元素theElement并使其索引为theIndex(插入)
template <class T>
void chain<T>::insert(int theIndex, const T &theElement)
{
    if (theIndex < 0 || theIndex > listSize)
    {
        cout << "无效索引";
    }
    if (theIndex == 0)
    {
        // 表头插入
        firstNode = new chainNode<T>(theElement, firstNode);
    }
    else
    {
        // 寻找新元素的前驱
        chainNode<T> *p = firstNode;
        for (int i = 0; i < theIndex - 1; i++)
        {
            p = p->next;
        }
        // 在p之后插入
        p->next = new chainNode<T>(theElement, p->next);
    }
    listSize++;
}

// 删除
template <class T>
int chain<T>::erase(T &theElement)
{
    chainNode<T> *deleteNode;
    chainNode<T> *currentNode = firstNode;
    int Index;
    while (currentNode != NULL || currentNode->element != theElement)
    {
        currentNode = currentNode->next;
        Index++;
    }
    if (currentNode == NULL)
    {
        return -1;
    }
    else
    {
        if (Index == 0)
        {
            deleteNode = firstNode;
            firstNode = firstNode->next;
        }
        else
        {
            chainNode<T> *p = firstNode;
            for (int i = 0; i < Index - 1; i++)
            { // 寻找需要删除的节点的前一个节点
                p = p->next;
            }
            deleteNode = p->next;
            p->next = p->next->next;
        }
        listSize--;
        delete deleteNode; // 删除需要删除的节点
    }
    return -1;
}

template <class T>
void chain<T>::zhihuan()
{
    chainNode<T> *p1, *p2;
    p1 = firstNode;
    p2 = p1->next;
    while (p2 != NULL)
    {
        //
        p1->next = p2->next;
        p2->next = firstNode;
        firstNode = p2;
        p2 = p1->next;
    }
    // p2 = firstNode;
    // p2->next = p3;
    // p1 = p1->next;
    // p1->next = NULL;
}

// 输出
template <class T>
int chain<T>::output()
{
    int j = 0;
    int a = 0;
    for (chain<T>::iterator i(firstNode); i != NULL; j++, i++)
    {
        a = a + ((*i) ^ j);
    }
    return a;
}
int main()
{
    int N, Q;
    cin >> N >> Q;
    chain<int> chain1(N);
    // 输入链表
    for (int i = 0; i < N; i++)
    {
        int c = 0;
        cin >> c;
        chain1.insert(i, c);
    }
    int s[Q];
    int k = 0;
    for (int i = 0; i < Q; i++)
    {
        int x = 0;
        cin >> x;
        switch (x)
        {
        case 1:
        {
            int w;
            int d;
            cin >> w >> d;
            chain1.insert(w, d);
        }
        break;
        case 2:
        {
            int w;
            cin >> w;
            s[k] = chain1.erase(w);
            k++;
        }
        break;
        case 3:
        {
            chain1.zhihuan();
        }
        break;
        case 4:
        {
            int w;
            cin >> w;
            s[k] = chain1.indexOf(w);
            k++;
        }
        break;
        case 5:
        {
            s[k] = chain1.output();
            k++;
        }
        }
    }
    for (int y = 0; y < k; y++)
    {
        cout << s[y] << endl;
    }
    return 0;
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值