实验2、基于顺序表的非递减有序表的合并

头文件

#pragma once
#ifndef EXPR1_H_

#define EXPR1_H_
#include <cstddef>
#include <iostream>
#include <memory>
#include <new>
#include <stdexcept>
template <typename T>
class expr1List
{
public:
    struct Node
    {
        T data;
        Node* prior;
        Node* next;
        Node()
        {
            prior = nullptr;
            next = nullptr;
        }
    };

private:
    Node* _head;
    Node* _rear;
    int _length;

public:
    expr1List();
    expr1List(std::initializer_list<T>);
    expr1List(const expr1List<T>&);
    ~expr1List();            //DestroyList(&L)
    void Clear();            //ClearList(&L)
    bool isEmpty() const;    //ListEmpty(L)
    int length() const;      //ListLength()
    T operator[](int) const; //为了List<T>类型的常量
    T& operator[](int);      //GetElem(L,i,&e)
    template <typename F>
    int locateElem(T, F) const; //LoacteElem(L,e,&e)
    int priorElem(T) const;     //改为返回直接前驱的索引,若失败,返回-1
    int nextElem(T) const;      //改为返回直接后驱的索引,若失败,返回-1
    bool listInsert(int, T);    //ListInsert()
    bool listDelete(int, T&);  //删除第i个元素,并将值返回给调用者
    bool isSorted();
    bool push_back(T);
    template <typename F>
    void traverse(F); //ListTraverse(L,visit())

    // iterator begin() { return iterator(_head); }
    // iterator end() { return iterator(_rear->next); }
};

template <typename T>
inline expr1List<T>::expr1List() : _head(nullptr), _rear(nullptr), _length(0) {}

template <typename T>
inline expr1List<T>::expr1List(std::initializer_list<T> il) : expr1List()
{
    int i = 0;
    for (auto p = il.begin(); p != il.end(); p++)
        listInsert(i++, *p);
}
template <typename T>
inline expr1List<T>::expr1List(const expr1List<T>& li):expr1List()
{
    int i = 0;
    while (i < li.length())
    {
        listInsert(i, li[i]);
        i++;
    }
}

template <typename T>
inline expr1List<T>::~expr1List() { Clear(); }

template <typename T>
inline void expr1List<T>::Clear()
{
    if (!_head)
        return;
    if (_length == 1)
    {
        _length = 0;
        delete _head;
        _head = nullptr;
        _rear = nullptr;
        return;
    }
    for (auto p = _head; p != _rear;)
    {
        Node* tmp = p;
        p = p->next;
        delete tmp;
    }
    delete _rear;
    _head = nullptr;
    _rear = nullptr;
    _length = 0;
}

template <typename T>
inline bool expr1List<T>::isEmpty() const
{
    return !_length;
}

template <typename T>
inline int expr1List<T>::length() const
{
    return _length;
}

template <typename T>
inline T expr1List<T>::operator[](int index) const
{
    if (index < 0 || index > _length - 1)
        throw std::out_of_range("下标越界了!");
    int i = 0;
    Node* p = _head;
    while (i != index)
    {
        p = p->next;
        i++;
    }
    return p->data;
}

template <typename T>
inline T& expr1List<T>::operator[](int index)
{
    if (index < 0 || index > _length - 1)
        throw std::out_of_range("下标越界了!");
    int i = 0;
    Node* p = _head;
    while (i != index)
    {
        p = p->next;
        i++;
    }
    return p->data;
}

template <typename T>
template <typename F>
inline int expr1List<T>::locateElem(T t, F f) const
{
    if (_length == 0)
        return -1;
    for (int i = 0; i < _length; i++)
        if (f(t, this->operator[](i)))
            return i;
    return -1;
}

template <typename T>
inline int expr1List<T>::priorElem(T t) const
{
    if (_length < 2)
        return -1;
    for (int i = 1; i < _length; i++)
        if (t == this->operator[](i))
            return i - 1;
    return -1;
}

template <typename T>
inline int expr1List<T>::nextElem(T t) const
{
    if (_length < 2)
        return -1;
    for (int i = 0; i < _length - 1; i++)
        if (t == this->operator[](i))
            return i + 1;
    return -1;
}

template <typename T>
inline bool expr1List<T>::listInsert(int l, T t)
{
    if (l < 0 || l > _length)
        return false;

    Node* newNode = new Node;
    if (!newNode)
        return false;
    newNode->data = t;
    _length++;

    if (l == 0) //如果插入第一个元素
    {
        if (_length == 1)
        {
            newNode->prior = newNode;
            newNode->next = newNode;
            _rear = newNode;
            _head = newNode;
            return true;
        }
        newNode->prior = _rear;
        newNode->next = _head;
        _head->prior = newNode;
        _rear->next = newNode;
        _head = newNode;

        return true;
    }

    int i = 0;
    Node* p = _head;
    while (i != l)
    {
        p = p->next;
        i++;
    }
    newNode->next = p;
    newNode->prior = p->prior;
    newNode->prior->next = newNode;
    newNode->next->prior = newNode;
    if (l == _length - 1)
        _rear = newNode;
    return true;
}

template <typename T>
inline bool expr1List<T>::listDelete(int l, T& t)
{
    if (l < 0 || l > _length - 1)
        return false;
    _length--;

    int i = 0;
    Node* p = _head;
    while (i != l)
    {
        p = p->next;
        i++;
    }
    if (l == 0)
        _head = p->next;
    if (l == _length - 1)
        _rear = p->prior;

    p->prior->next = p->next;
    p->next->prior = p->prior;
    delete p;
    return true;
}
template <typename T>
inline bool expr1List<T>::isSorted()
{
    if (_length < 2)
        return true;
    for (int i = 1; i < _length; i++)
        if (this->operator[](i) < this->operator[](i - 1))
            return false;
    return true;
}

template <typename T>
bool expr1List<T>::push_back(T t)
{
    Node* newNode = new Node;
    newNode->data = t;
    if (_length == 0)
    {
        newNode->prior = newNode;
        newNode->next = newNode;
        _head = _rear = newNode;
        _length++;
        return true;
    }
    newNode->prior = _rear;
    newNode->next = _head;
    _head->prior = newNode;
    _rear->next = newNode;
    _rear = newNode;
    _length++;
    return true;
}
template <typename T>
template <typename F>
inline void expr1List<T>::traverse(F f)
{
    if (_length == 0)
        return;
    for (int i = 0; i < _length; i++)
        f(this->operator[](i));
}

#endif // !EXPR1_H_
#include "expr1.h"
#include <cctype>
#include <memory>
using namespace std;
template <typename T>
void MergeList(T, T, T&);
void showMenu();
void showError() { cout << "请先初始化一个线性表!" << endl; }
template <typename T>
void input(expr1List<T>& li, bool sortedCheck = false);
template <typename T>
void showList(const expr1List<T>&);
expr1List<int>* l1 = nullptr;
bool status = false;
int main()
{
    showMenu();
    int selection;
    while (true)
    {
        cout << "请输入操作代码:";
        cin >> selection;
        if (selection < 0)
            break;
        switch (selection)
        {
        case 1:
        {
            if (!status)
            {
                l1 = new expr1List<int>;
                if (cin.peek() == '\n')
                    cin.get();

                input(*l1);
                status = true;
                cout << "初始化完成!" << endl;
            }
            else
                cout << "已经初始化过了。" << endl;
        }
        break;
        case 2:
        {
            if (status)
            {
                delete l1;
                status = false;
                cout << "链表已销毁!" << endl;
            }
            else
                showError();
            break;
        }
        case 3:
        {
            if (status)
            {
                l1->Clear();
                cout << "线性表已清空!" << endl;
            }
            else
                showError();
            break;
        }
        case 4:
        {
            if (status)
            {
                if (l1->isEmpty())
                    cout << "线性表是空的!" << endl;
                else
                    cout << "线性表不是空的!" << endl;
            }
            else
                showError();
            break;
        }
        case 5:
        {
            if (status)
                cout << "线性表长度为" << l1->length() << endl;
            else
                showError();
            break;
        }
        case 6:
        {
            if (status)
            {
                if (l1->length() == 0)
                {
                    cout << "线性表里什么都没有呢!" << endl;
                    break;
                }
                int n;
                do
                {
                    printf("请输入指定的位置,区间要在[0,%d):", l1->length());
                    cin >> n;
                } while (n < 0 || n > l1->length() - 1);
                cout << "第" << n << "位的值是" << l1->operator[](n) << endl;
            }
            else
                showError();
            break;
        }
        case 7:
        {
            if (status)
            {
                int n;
                cout << "请输入元素:";
                cin >> n;
                int e = l1->locateElem(n, [](int n, int m) { return n == m; });
                if (e == -1)
                    cout << "呀!找不到该元素。" << endl;
                else
                    cout << "这个元素在线性表最靠前的位置是" << e << endl;
            }
            else
                showError();
            break;
        }
        case 8:
        {
            if (status)
            {
                int n;
                cout << "请输入要求前驱的元素:";
                cin >> n;
                int e = l1->locateElem(n, [](int n, int m) { return n == m; });
                if (e == -1)
                {
                    cout << "呀!找不到该元素。" << endl; break;
                }
                int index = l1->priorElem(n);
                if (index == -1)
                    cout << "这个元素没有前驱。" << endl;
                else
                    cout << "这个元素的前驱是" << l1->operator[](index) << endl;
            }
            else
                showError();
            break;
        }
        case 9:
        {
            if (status)
            {
                int n;
                cout << "请输入要求后继的元素:";
                cin >> n;
                int e = l1->locateElem(n, [](int n, int m) { return n == m; });
                if (e == -1)
                {
                    cout << "呀!找不到该元素。" << endl; break;
                }
                int index = l1->nextElem(n);
                if (index == -1)
                    cout << "这个元素没有后继。" << endl;
                else
                    cout << "这个元素的后继是" << l1->operator[](index) << endl;
            }
            else
                showError();
            break;
        }
        case 10:
        {
            if (status)
            {
                int index;
                int n;
                do
                {
                    cout << "请输入一个正确的位置:";
                    cin >> index;
                } while (index < 0 || index > l1->length());
                cout << "请输入元素:";
                cin >> n;
                l1->listInsert(index, n);
                cout << "插入成功!" << endl;
            }
            else
                showError();
            break;
        }
        case 11:
        {
            if (status)
            {
                int index;
                int n;
                do
                {
                    cout << "请输入一个正确的位置:";
                    cin >> index;
                } while (index < 0 || index > l1->length() - 1);
                l1->listDelete(index, n);
                cout << "删除成功!" << endl;
            }
            else
                showError();
            break;
        }
        case 12:
        {
            if (status)
                showList(*l1);
            else
                showError();
            break;
        }
        case 13:
        {
            expr1List<int> la, lb, lc;
            cout << "请输入两个非递减有序的线性表。" << endl;
            cout << "第一个:" << endl;
            if (cin.peek() == '\n')
                cin.get();
            input(la, true);
            cout << "第二个" << endl;
            if (cin.peek() == '\n')
                cin.get();
            input(lb, true);
            MergeList(la, lb, lc);
            cout << "合并结果:";
            showList(lc);
        }
        default:
            cout << "请输入1-13以内的数,或者一个负数" << endl;
        }
    }
    cout << "拜拜!" << endl;
    if (status)
        delete l1;
    system("pause");
}

template <typename T>
void MergeList(T La, T Lb, T& Lc)
{
    int i = 0;
    int j = 0;
    int k = 0;
    while (i != La.length() && j != Lb.length())
    {
        if (La[i] <= Lb[j])
        {
            Lc.listInsert(k++, La[i]);
            if (La[i++] == Lb[j])
                j++;
        }
        else if (La[i] > Lb[j])
            Lc.listInsert(k++, Lb[j++]);
    }
    while (i != La.length())
        Lc.listInsert(k++, La[i++]);
    while (j != Lb.length())
        Lc.listInsert(k++, Lb[j++]);
}
void showMenu()
{
    cout << "=============实验二(李金宝)================" << endl
        << "1----初始化一个线性表" << endl
        << "2----销毁线性表" << endl
        << "3----清空线性表" << endl
        << "4----判断线性表是否为空" << endl
        << "5----求线性表长度" << endl
        << "6----获取线性表中指定的位置" << endl
        << "7----获取线性表元素的位置" << endl
        << "8----求前驱" << endl
        << "9----求后继" << endl
        << "10----在线性表指定位置插入元素" << endl
        << "11----删除线性表指定位置的元素" << endl
        << "12----显示线性表" << endl
        << "13----合并两个非递减有序的线性表" << endl
        << "      退出,输入一个负数!" << endl
        << endl;
}

template <typename T>
void input(expr1List<T>& li, bool sortedCheck)
{
    cout << "请输入一个线性表(以“Enter”结束输入):";
    if (cin.peek() == '\n')
    {
        cin.get(); return;
    }
    int n = 0;
    do
    {
        li.Clear();
        if (sortedCheck)
            cout << "要有序!!!" << endl;
        while (cin >> n)
        {
            li.push_back(n);
            if (cin.peek() == '\n')
            {
                cin.get();
                break;
            }
        }
        if (!sortedCheck)
            return;
    } while (cin.clear(), cin.sync(), !li.isSorted());
}
template <typename T>
void showList(const expr1List<T>& li)
{
    int i = 0;
    cout << endl;
    while (i < li.length())
        cout << li[i++] << "  ";
    cout << endl;
}
  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值