1
0
Fork 0
You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

364 lines
8.7 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#ifndef SEQLIST_H
#define SEQLIST_H
#include "PerfCounter.h"
#include <cassert>
#include <cstdlib>
#include <iostream>
using namespace std;
#include "LinearList.h"
;
const int defaultSize = 100;
template <class T>
class SeqList : public LinearList<T>
{
protected:
T *data; //存放数组
int maxSize; //最大可容纳表项数
int last; //当前已存表项的最后位置从0开始
void reSize(int newSize); //改变data数组空间大小
public:
PerfCounter counter;
SeqList(int sz = defaultSize); //构造函数
SeqList(SeqList<T> &L); //复制构造函数
~SeqList()
{
delete[] data;
} //析构函数
int Size() const
{ //计算表的最大可容纳表项个数
return maxSize;
}
int Length() const
{ //计算表长度
return last + 1;
}
int Search(T &x) const; //搜索x在表中的位置函数返回表项序号
int Locate(int i) const; //定位第i个表项函数返回表项序号
bool getData(int i, T &x) const //取第i个表项的值 放入x中
{
if (i > 0 && i <= last + 1)
{
x = data[i - 1];
return true;
}
else
{
return false;
}
}
void setData(int i, T &x) //用x修改第i个表项的值
{
if (i > 0 && i <= last + 1)
{
data[i - 1] = x;
}
}
bool Insert(int i, T &x); //插入x在第i个表项后
bool Remove(int i, T &x); //删除第i个表项通过x返回表项的值
bool IsEmpty() const //判断表空否空返回true否则返回false
{
return (last == -1) ? true : false;
}
bool IsFull() const //判断表满否满返回true否则返回false
{
return (last == maxSize - 1) ? true : false;
}
void Sort(); //排序
void input(); //输入
void output(); //输出
SeqList<T> *operator=(SeqList<T> &L)
{
T value;
maxSize = L.Size();
last = L.Length() - 1;
//delete []data;//先清空
data = new T[maxSize];
if (data == NULL)
{
cerr << "Memory allocating error!" << endl;
exit(1);
}
for (int i = 1; i <= last + 1; i++)
{
L.getData(i, value);
data[i - 1] = value;
}
return this;
}
///增加的函数成员://///////////////////////////////////////////////////////////////////////////////////////////////////////
void OrderInsert(T &item); //有序顺序表的有序插入
void OrderMake(T *d, int len); //构造有序顺序表
void MoreRemove(T &x); //删除有序顺序表值为x的重复元素
void Merge(const SeqList &La, const SeqList &Lb); //归并有序表La和Lb
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
};
template <class T>
SeqList<T>::SeqList(int sz)
{
if (sz > 0)
{
maxSize = sz;
last = -1;
data = new T[maxSize];
if (data == NULL)
{
cerr << "Memory allocating error!" << endl;
exit(1);
}
}
}
template <class T> //复制构造函数
SeqList<T>::SeqList(SeqList<T> &L)
{
T value;
maxSize = L.last();
last = L.Length() - 1;
data = new T[maxSize];
if (data == NULL)
{
cerr << "Memory allocating error!" << endl;
exit(1);
}
for (int i = 1; i <= last + 1; i++)
{
L.getData(i, value);
data[i - 1] = value;
}
}
template <class T> //扩容至元素个数为newSize个
void SeqList<T>::reSize(int newSize)
{
if (newSize <= 0)
{
cerr << "Invalid array index!" << endl;
return;
}
if (newSize != maxSize)
{
T *newarray = new T[newSize];
if (newarray == NULL)
{
cerr << "Memory allocating error!" << endl;
exit(1);
}
int n = last + 1;
T *srcptr = data;
T *destptr = newarray;
while (n--)
*destptr++ = *srcptr++;
delete[] data;
data = newarray;
maxSize = newSize;
}
}
template <class T> //查找第一个值为x的元素下标
int SeqList<T>::Search(T &x) const
{
for (int i = 0; i <= last; i++)
{
if (data[i] == x)
return i + 1;
}
return 0;
}
template <class T> //定位第i个元素的位置
int SeqList<T>::Locate(int i) const
{
if (i >= 1 && i <= last + 1)
return i;
else
return 0;
}
template <class T> //在第i个元素后插x
bool SeqList<T>::Insert(int i, T &x)
{
if (last == maxSize - 1)
return false;
if (i < 0 || i > last + 1)
return false;
for (int j = last; j >= i; j--)
data[j + 1] = data[j];
data[i] = x;
last++;
return true;
}
template <class T> //删除第i个元素并通过x返回
bool SeqList<T>::Remove(int i, T &x)
{
if (last == -1)
return false;
if (i < 1 || i > last + 1)
return false;
x = data[i - 1];
for (int j = i; j <= last; j++)
data[j - 1] = data[j];
last--;
return true;
}
template <class T>
void SeqList<T>::Sort()
{ //冒泡排序:从小到大排序
for (int i = 1; i <= last; i++)
{
for (int j = last; j >= i; j--)
{
if (data[j - 1] > data[j])
{
T tmp = data[j - 1];
data[j - 1] = data[j];
data[j] = tmp;
}
}
}
}
template <class T> //从键盘逐个输入数据并建立顺序表
void SeqList<T>::input()
{
cout << "开始建立顺序表请输入表中元素个数Input the size of the list which will be created:";
while (1)
{
assert(cin >> last);
last--;
if (last < 0)
{
cout << "Input error, the last must be positive!\n";
cout << "Input the last again:";
}
else if (last > maxSize - 1)
{
cout << "Input error, the last must be less than maxSize!\n";
cout << "Input the last again:";
}
else
break;
}
cout << "\nInput the data for each element to create the list:" << endl;
for (int i = 0; i <= last; i++)
{
cout << "#" << i + 1 << ":";
assert(cin >> data[i]);
}
}
template <class T> //将顺序表输出到屏幕
void SeqList<T>::output()
{
cout << "\nThe size of the list is:" << last + 1 << endl;
for (int i = 0; i <= last; i++)
cout << "#" << i + 1 << ":\t" << data[i] << endl;
}
/**
* OrderInsert()在有序顺序表L中的合适位置插入数据元素x使得L中的数据元素按值非递减有序排列。
**/
template <class T>
void SeqList<T>::OrderInsert(T &item)
{
//在这里加入实现第一个任务的程序。
int pos = 0;
for (; pos <= last; pos++)
{
counter.inc_cmp(1);
if (data[pos] >= item)
break;
}
for (int j = last; j >= pos; j--)
data[j + 1] = data[j], counter.inc_mov(1);
data[pos] = item, counter.inc_mov(1);
last++;
}
/**
* MoreRemove()在有序顺序表L中删除所有值为x的元素。
**/
template <class T>
void SeqList<T>::MoreRemove(T &x)
{
//在这里加入实现第三个任务的程序。
//有序顺序表中可能有重复的x值删除有序顺序表中重复的x值.
//要求算法尽可能高效——尽可能减少移动元素的次数。
//在你的readme.txt文件中描述算法并分析算法的时间复杂度和空间复杂度。
counter.inc_mem(8);
int pos1 = -1, pos2 = -1;
for (int i = 0; i <= last; i++)
{
counter.inc_cmp(1);
if (data[i] == x)
{
pos2 = pos1 = i;
while (data[pos2] == x) counter.inc_cmp(1), pos2++;
break;
}
}
if (pos1 == -1) return;
int dif = pos2 - pos1;
int newLast = last - dif;
for (int i = pos1; i <= newLast; i++)
data[i] = data[i + dif], counter.inc_mov(1);
last = newLast, counter.inc_mov(1);
}
/**
* OrderMake()从数组d依次取len个数据元素有序插入到有序顺序表L中。
**/
template <class T>
void SeqList<T>::OrderMake(T *d, int len)
{
for (int i = 0; i < len; i++)
OrderInsert(d[i]);
}
//有序表的合并。认真学习该算法。
template <class T>
void SeqList<T>::Merge(const SeqList &La, const SeqList &Lb)
{
int i, j;
T xa, xb;
last = -1;
i = 1;
j = 1;
while (i <= La.Length() && j <= Lb.Length()) /*两个表中都有元素未比完*/
{
if (last == maxSize - 1)
reSize(2 * maxSize);
La.getData(i, xa);
Lb.getData(j, xb);
if (xa <= xb)
{
Insert(last + 1, xa);
i++;
}
else
{
Insert(last + 1, xb);
j++;
}
}
while (i <= La.Length()) /*Lb表的元素已经比完*/
{
if (last == maxSize - 1) reSize(2 * maxSize);
La.getData(i, xa);
Insert(last + 1, xa);
i++;
}
while (j <= Lb.Length()) /*La表的元素已经比完*/
{
if (last == maxSize - 1) reSize(2 * maxSize);
Lb.getData(j, xb);
Insert(last + 1, xb);
j++;
}
}
#endif