chainNode.h
#pragma once
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;
}
};
chain.h
#pragma once
#include<iostream>
#include"chainNode.h"
using namespace std;
template<class T>
class chain
{
protected:
void checkIndex(int theIndex)const;
chainNode<T> *firstNode; // 指向链表第一个节点的指针
int listSize; // 线性表的元素个数
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()const;
};
chain.cpp
#include "chain.h"
template<class T>
void chain<T>::checkIndex(int theIndex) const
{
if (theIndex < 0 || theIndex >= listSize) {
cout << "index = " << theIndex << " size = " << listSize;
exit(-1);
}
}
template<class T>
chain<T>::chain(int initialCapacity)
{
if (initialCapacity < 1) {
cout << "Initial capacity = " << initialCapacity << " Must be > 0";
exit(-1);
}
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;
firstNode = new chainNode<T>(sourceNode->element);
sourceNode = sourceNode->next;
chainNode<T>* targetNode = firstNode;
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;
}
}
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;
// TODO: 在此处插入 return 语句
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{
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;
}
}
template<class T>
void chain<T>::erase(int theIndex)
{
checkIndex(theIndex);
chainNode<T>* deleteNode;
if (theIndex == 0) {
deleteNode = firstNode;
firstNode = firstNode->next;
}
else {
chainNode<T> *p = firstNode;
for (int i = 0;i < theIndex-1;i++) {
p = p->next;
}
//p最后指向要删除节点的前一节点
deleteNode = p->next;
p->next= deleteNode->next;
}
delete deleteNode;
listSize--;
}
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
if (theIndex < 0 || theIndex > listSize) {
cout << "index = " << theIndex << " size = " << listSize;
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;
}
p->next = new chainNode<T>(theElement, p->next);
}
listSize++;
}
template<class T>
void chain<T>::output() const
{
chainNode<T>* currentNode = firstNode;
for (;currentNode != NULL;currentNode = currentNode->next) {
cout << currentNode->element << " ";
}
}
Test.cpp
#include<iostream>
using namespace std;
#include"chain.h"
#include"chain.cpp"
int main() {
chain<int> c1;
if (c1.empty()) {
cout << "链表为空\n";
}
else {
cout << "链表不为空\n";
}
c1.insert(0, 2);
c1.insert(1, 6);
c1.insert(0, 1);
c1.insert(2, 4);
c1.insert(3, 5);
c1.insert(2, 3);
cout << "链表长度为:" << c1.size() << "\n";
c1.output();
cout << "\n";
int index = c1.indexOf(4);
if (index < 0) cout << "4 not found" << endl;
else cout << "The index of 4 is " << index << endl;
index = c1.indexOf(7);
if (index < 0) cout << "7 not found" << endl;
else cout << "The index of 7 is " << index << endl;
// test get
cout << "Element with index 0 is " << c1.get(0) << endl;
cout << "Element with index 3 is " << c1.get(3) << endl;
c1.erase(1);
cout << "Element 1 erased" << endl;
c1.erase(2);
cout << "Element 2 erased" << endl;
c1.erase(0);
cout << "Element 0 erased" << endl;
cout << "Size of c1 = " << c1.size() << endl;
if (c1.empty()) cout << "c1 is empty" << endl;
else cout << "c1 is not empty" << endl;
c1.output();
cout << "\n";
chain<int> c2(c1);
c2.insert(0, 100);
c2.insert(0, 200);
c2.insert(0, 300);
c2.output();
return 0;
}