数组描述线性表
#pragma warning(disable:4996)
#include <iostream>
#include<iterator>
#include<algorithm>
using namespace std;
//边长一维数组(增加或减少)
//改变一个一维数组的长度
template<class T>
void changeLength1D(T*& a, int oldLength, int newLength)
{
if (newLength < 0)
{
cout << "错误:newLength 小于 0!";
exit(-1);
}
T* temp = new T[newLength];
int number = min(oldLength, newLength);
copy(a, a + number, temp);
delete[] a;
a = temp;
}
//一个线性表的抽象类
template<class T>
class linearList
{
public:
virtual ~linearList() {};
//当线性表为空时,返回true
virtual bool empty() const = 0;//后面加 const表示函数不可以修改class的成员,其实就是对this指针进行了const
//返回线性表元素的个数
virtual int size() const = 0;
//返回索引为theIndex的元素
virtual T& get(int theIndex) const = 0;
//删除索引为theIndex的元素
virtual void erase(int theIndex) = 0;
//把theElement插入线性表中索引为theIndex的位置上
virtual void insert(int theIndex, const T& theElement) = 0;
};
template<class T>
class arrayList:public linearList<T>
{
public:
arrayList(int initialCapacity = 10);
arrayList(const arrayList<T>& theList);
~arrayList() { delete[] element; }
bool empty() const { return listSize == 0; }
int size() const { return listSize; }
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
int capacity() const { return arrayLength; }
void output(ostream& out) const;
protected:
void checkIndex(int theIndex) const;
friend ostream& operator<<(ostream& out, const arrayList<T>& x);
int arrayLength;
int listSize;
T* element;
};
template<class T>
arrayList<T>::arrayList(int initialCapacity = 10)
{
arrayLength = initialCapacity;
element = new T[arrayLength];
listSize = 0;
}
template<class T>
arrayList<T>::arrayList(const arrayList<T>& theList)
{
arrayLength = theList.arrayLength;
listSize = theList.listSize;
element = new T[arrayLength];
copy(theList.element, theList.element + listSize, element);
}
template<class T>
void arrayList<T>::checkIndex(int theIndex) const
{
if (theIndex < 0 || theIndex >= listSize)
{
cout << "错误:theIndex 不合法!";
exit(-1);
}
}
template<class T>
T& arrayList<T>::get(int theIndex) const
{
checkIndex(theIndex);
return element[theIndex];
}
template<class T>
int arrayList<T>::indexOf(const T& theElement) const
{
int theIndex = (int)(find(element, element + listSize, theElement) - element);
if (theIndex == listSize)
return -1;
else
return theIndex;
}
template<class T>
void arrayList<T>::erase(int theIndex)
{
checkIndex(theIndex);
copy(element + theIndex + 1, element + listSize, element + theIndex);
//下标是从0开始的,把最后一个位置析构掉
element[--listSize].~T();
}
template<class T>
void arrayList<T>::insert(int theIndex, const T& theElement)
{
if (theIndex <0 || theIndex > listSize)
{
cout << "元素插入的theIndex下标不合理! ";
exit(-1);
}
//有效索引,确定数组是否已满
if (listSize == arrayLength)
{
changeLength1D(element, arrayLength, 2 * arrayLength);
arrayLength *= 2;
}
//把元素向右移动一个位置
copy_backward(element + theIndex, element + listSize, element + listSize + 1);
element[theIndex] = theElement;
listSize++;
}
template<typename T> ostream& operator<<(ostream& out, const arrayList<T>& x)
{
x.output(out);
return out;
}
template<typename T> void arrayList<T>::output(ostream& out) const
{
//把线性表插入输出流
copy(element, element + listSize, ostream_iterator<T>(cout, " "));
}
int main()
{
arrayList<int> a(8);
//测试insert函数
a.insert(0, 5);
a.insert(1, 4);
a.insert(2, 3);
a.insert(3, 2);
a.insert(0, 1);
//测试output函数
cout << "初始线性表为:";
a.output(cout);
cout << endl;
cout << "初始线性表的大小为:" << a.size() << endl;
//测试erase函数
cout << "删除theIndex = 2的元素后线性表为:";
a.erase(2);
a.output(cout);
cout << "线性表的大小为: " << a.size() << endl;
//测试indexOf函数
cout << "元素值为5的下标是:" << a.indexOf(5) << endl;
//测试get函数
cout << "下标为1的元素是:" << a.get(1) << endl;
system("pause");
return 0;
}
链表描述线性表
#pragma warning(disable:4996)
#include <iostream>
#include<iterator>
#include<algorithm>
using namespace std;
//一个线性表的抽象类
template<class T>
class linearList
{
public:
virtual ~linearList() {};
//当线性表为空时,返回true
virtual bool empty() const = 0;//后面加 const表示函数不可以修改class的成员,其实就是对this指针进行了const
//返回线性表元素的个数
virtual int size() const = 0;
//返回索引为theIndex的元素
virtual T& get(int theIndex) const = 0;
//删除索引为theIndex的元素
virtual void erase(int theIndex) = 0;
//把theElement插入线性表中索引为theIndex的位置上
virtual void insert(int theIndex, const T& theElement) = 0;
};
//链表节点的结构定义
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 linearList<T>
{
public:
chain(int initialCapacity = 10);
chain(const chain<T>&);
~chain();
bool empty() const { return listSize == 0; }
int size() const { return listSize; }
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(ostream& out) const;
protected:
friend ostream& operator<<(ostream& out, const chain<T>& x);
//指向链表第一个节点的指针
chainNode<T>* firstNode;
//线性表的元素个数
int listSize;
};
template<class T>
chain<T>::chain(int initialCapacity)
{
if (initialCapacity < 1)
{
cout << "初始化的容量个数不能小于1" << endl;
}
firstNode = NULL;
listSize = 0;
}
template<class T>
chain<T>::chain(const chain<T>& theList)
{
listSize = theList.listSize;
if (listSize == 0)
{
firstNode = NULL;
listSize = 0;
}
//链表theList非空
//用一个指针指向theList的首节点
chainNode<T>* sourceNode = theList.firstNode;
//赋值链表theList的首元素
firstNode = new chainNode<T>(sourceNode->element);
sourceNode = sourceNode->next;
chainNode<T>* targetNode = firstNode;
while (targetNode != NULL)
{
targetNode->next = new chainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
sourceNode->next = NULL;
}
template<class T>
chain<T>::~chain()
{
while (firstNode != NULL)
{
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template<class T>
T& chain<T>::get(int theIndex) const
{
if (theIndex<0 || theIndex>listSize)
{
cout << "输入合法的theIndex" << endl;
exit(-1);
}
chainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{
chainNode<T>* currentNode = firstNode;
int index = 0;
while (currentNode->element != theElement)
{
currentNode = currentNode->next;
index++;
}
if (currentNode == NULL)
return -1;
else
return index;
}
/*
erase需要考虑三种情况:
1.索引无效
2.删除非空表的第0个元素节点
3.删除其它元素节点
*/
template<class T>
void chain<T>::erase(int theIndex)
{
//索引无效
if (theIndex<0 || theIndex>listSize)
{
cout << "输入合法的theIndex" << endl;
exit(-1);
}
chainNode<T>* deleteNode;
if (theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
}
else
{
chainNode<T>* p = firstNode;
//要删除某个节点需要找其前一个节点,也就是p
for (int i = 0; i < theIndex-1; ++i)
p = p->next;
deleteNode = p->next;
p->next = p->next->next;
}
listSize--;
delete deleteNode;
}
//插入和删除一样,也得讨论三种情况
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
//索引无效
if (theIndex<0 || theIndex>listSize)
{
cout << "输入合法的theIndex" << endl;
exit(-1);
}
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;
//新创建一个节点,值为theElement,这个新节点的next为p->next
p->next= new chainNode<T>(theElement, p->next);
}
listSize++;
}
//输出链表
template<class T>
void chain<T>::output(ostream& out) const
{
for (chainNode<T>* currentNode = firstNode; currentNode != NULL;
currentNode = currentNode->next)
out << currentNode->element << " ";
}
template<class T>
ostream& operator<<(ostream& out, const chain<T>& x)
{
x.output(out);
return out;
}
int main()
{
chain<int> c;
//测试insert函数
c.insert(0, 5);
c.insert(1, 4);
c.insert(2, 3);
c.insert(3, 2);
c.insert(0, 1);
//测试output函数
cout << "初始线性表为:";
c.output(cout);
cout << endl;
cout << "初始线性表的大小为:" << c.size() << endl;
//测试erase函数
cout << "删除theIndex = 2的元素后线性表为:";
c.erase(2);
c.output(cout);
cout << "线性表的大小为: " << c.size() << endl;
//测试indexOf函数
cout << "元素值为5的下标是:" << c.indexOf(5) << endl;
//测试get函数
cout << "下标为1的元素是:" << c.get(1) << endl;
system("pause");
return 0;
}