头文件
#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;
}