数据结构、算法与应用 C++语言描述 第6章习题
数据结构、算法与应用 C++语言描述 第6章习题1、chain.h文件 所包含的部分算法2、extendChain.h 部分习题3、doubleLinkedList.h4、doubleCircleList.h5、circleListWithHeader.h6、doubleCircularListWithHeader.hlinearList.h 和之前章节的相同1、chain.h文件 所包含的部分算
·
数据结构、算法与应用 C++语言描述 第6章习题
linearList.h 和之前章节的相同
1、chain.h文件 所包含的部分算法
#ifndef CHAIN_H
#define CHAIN_H
#include "linearList.h"
#include "arrayList.h"
#include <algorithm>
#include <iostream>
#include <sstream>
template <class T>
struct chainNode
{
// data member
T element;
chainNode<T>* next;
// function
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>
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const chain<U>& x);
public:
chain(int initialCapacity = 10);
chain(const chain<T>& theChain);
~chain();
bool empty() const {return listSize == 0;} // 调用STL库的方法
int size() const {return listSize;} // STL
T& get(int theIndex) const override;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(std::ostream &out) const;
// Q18
void meld(chain<T>& leftChain, chain<T>& rightChain);
// Q20
void merge(chain<T>& leftChain, chain<T>& rightChain);
// Q22
void split(chain<T>& leftChain, chain<T>& rightChain);
// Q26
void insertSort();
// Q27
void bubbleSort();
void selectSort();
void countSort(){}
class myIterator
{
public:
// 构造函数
myIterator(chainNode<T>* theNode = NULL) {node = theNode;}
// 解引用操作符
T& operator*() const {return node->element;}
T* operator->() const {return &node->element;}
// 单向列表,只能递加操作,无递减操作
myIterator& operator++() {node = node->next; return *this;} // 先改变自身,然后返回一个指针
myIterator operator++(int) {myIterator p=*this; node = node->next;return p;} // 这里关于指针类型的问题很重要
// 相等检验
bool operator==(const myIterator& right) const {return node == right.node;}
bool operator!=(const myIterator& right) const {return node != right.node;}
protected:
chainNode<T>* node;
};
// 这里指针的值要进行显示转换,因为要支持迭代器的各种操作
myIterator begin() const {return myIterator(firstNode);}
myIterator end() const {return myIterator(NULL);}
protected:
void checkIndex(int theIndex) const;
chainNode<T>* firstNode; // 指向链表第一个节点的指针
int listSize; // 当前链表的长度
};
template <class T>
chain<T>::chain(int initialCapacity)
{
if(initialCapacity < 1)
{
std::ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
// throw s.str();
}
firstNode = NULL;
listSize = 0;
}
template <class T>
chain<T>::chain(const chain<T>& theList)
{
listSize = theList.listSize;
if(listSize == 0)
{
firstNode=NULL;
return;
}
// if the theChain is not empty
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>
void chain<T>::checkIndex(int theIndex) const
{
if(theIndex >= listSize)
throw "theIndex is bigger than listSize!";
}
template <class T>
T& chain<T>::get(const int theIndex) const
{
checkIndex(theIndex);
// 根据索引向前移动
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; // the index of current nodes
for(;currentNode != NULL; currentNode = currentNode->next)
{
if(theElement == currentNode->element) break;
index++;
}
if(currentNode == NULL)
return -1;
return index;
}
template <class T>
void chain<T>::erase(const int theIndex)
{
checkIndex(theIndex);
chainNode<T>* deleteNode, *currentNode = firstNode;
if(theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
}
else
{
for(int i=0;i<theIndex-1;i++)
currentNode = currentNode->next;
deleteNode = currentNode->next;
// here the next is the core problem
// currentNode is a point, so it can change its member "next" from the address
currentNode->next = currentNode->next->next;
}
listSize--;
delete deleteNode;
}
template <class T>
void chain<T>::insert(int theIndex, const T& theElement)
{
// 因为可以在尾后插入,且计数从0开始,所以要减一
checkIndex(theIndex - 1);
if(theIndex==0)
firstNode = new chainNode<T>(theElement, firstNode);
else
{
chainNode<T>* currentNode = firstNode;
for(int i=0;i<theIndex-1;i++)
currentNode = currentNode->next;
// here the next is the core problem
// currentNode is a point, so it can change its member "next" from the address
currentNode->next = new chainNode<T>(theElement, currentNode->next);
}
listSize++;
}
template <class T>
void chain<T>::output(std::ostream& out) const
{
for(chainNode<T>* currentNode=firstNode; currentNode != NULL; currentNode=currentNode->next)
out << currentNode->element << " ";
}
template <class T>
std::ostream& operator<<(std::ostream& out, chain<T>& theList)
{
theList.output(out);
return out;
}
template <class T>
void chain<T>::meld(chain<T>& leftChain, chain<T>& rightChain)
{
// 先释放原来的内存
for(int i=0; i<listSize; i++)
erase(0);
chainNode<T>* currentNode = NULL, *leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode;
int shareSize = std::min(leftChain.size(), rightChain.size());
// 下边这一段要好好揣摩,画图
// 尝试有没有更好的实现方法
for(int i=0; i<shareSize; i++)
{
if(i==0)
currentNode=leftNode;
else
{
currentNode->next=leftNode;
currentNode=currentNode->next;
}
leftNode=leftNode->next;
currentNode->next = rightNode;
rightNode=rightNode->next;
currentNode = currentNode->next;
}
if(leftChain.size() > rightChain.size())
currentNode->next=leftNode;
listSize = leftChain.size() + rightChain.size();
firstNode = leftChain.firstNode;
// 将输入链表设为空
leftChain.firstNode=NULL;
leftChain.listSize=0;
rightChain.firstNode=NULL;
rightChain.listSize=0;
}
template <class T>
void chain<T>::merge(chain<T>& leftChain, chain<T>& rightChain)
{
// 先释放原来的内存
for(int i=0; i<listSize; i++)
erase(0);
chainNode<T>* leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode, *currentNode = NULL;
// 首先确定第一个
if(leftNode->element < rightNode->element)
{
currentNode = leftNode;
leftNode = leftNode->next;
}
else
{
currentNode = rightNode;
rightNode = rightNode->next;
}
firstNode = currentNode; // 更新当前对象的头指针
while(leftNode != NULL && rightNode != NULL)
{
if(leftNode->element < rightNode->element)
{
currentNode->next = leftNode;
currentNode = currentNode->next;
leftNode = leftNode->next;
}
else
{
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
}
}
chainNode<T>* extraNode = (leftNode == NULL) ? rightNode : leftNode;
currentNode->next=extraNode;
listSize = leftChain.size() + rightChain.size();
leftChain.listSize = 0, rightChain.listSize = 0;
leftChain.firstNode = NULL, rightChain.firstNode = NULL;
}
template <class T>
void chain<T>::split(chain<T>& leftChain, chain<T>& rightChain)
{
for(int i=0; i<leftChain.size(); i++)
leftChain.erase(0);
for(int i=0; i<rightChain.size(); i++)
rightChain.erase(0);
typename chain<T>::myIterator fromIter = begin(), endIter = end();
while (fromIter != NULL)
{
leftChain.insert(leftChain.size(), *fromIter++);
if(fromIter == NULL)
break;
rightChain.insert(rightChain.size(), *fromIter++);
}
}
// 链表排序
// 也可以不利用指针操作,而是直接对指针内的元素进行元素替换
template <class T>
void chain<T>::insertSort()
{
// 第一个不用排序
chainNode<T>* preNode = firstNode, *currentNode = firstNode->next, *nextNode = currentNode->next;
for(int i=1; i<listSize; i++)
{
preNode->next = nextNode;
int j=0; // 用j记录firstnode是否被替换
chainNode<T>* searchLeftNode = NULL, * searchRightNode = firstNode;
for(j=0; j<i && currentNode->element > searchRightNode->element;j++)
{
searchLeftNode = searchRightNode;
searchRightNode = searchRightNode->next;
}
if(j == 0)
firstNode = currentNode;
else
searchLeftNode->next = currentNode;
currentNode->next = searchRightNode;
if(j == i)
preNode = currentNode; // 只有当currentNode放回原位时preNode才用迭代
currentNode = nextNode;
if(nextNode != NULL)
nextNode = nextNode->next;
}
}
// 冒泡排序
template <class T>
void chain<T>::bubbleSort()
{
for(int j=listSize; j>1; j--)
{
chainNode<T>* currentNode = firstNode, *nextNode = firstNode->next;
for(int i=0; i<j-1; i++)
{
if(currentNode->element > nextNode->element)
{
T tmp = currentNode->element;
currentNode->element = nextNode->element;
nextNode->element = tmp;
}
currentNode=nextNode;
nextNode=nextNode->next;
}
}
}
template <class T>
void chain<T>::selectSort()
{
// 找最大,方法类似
}
#endif
2、extendChain.h 部分习题
#ifndef EXTENDEDCHAIN_H
#define EXTENDEDCHAIN_H
#include "chain.h"
template <class T>
class extendedChain : public chain<T> // 这里一定要加模板类型T
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const extendedChain<U>& x);
public: // 这里访问基类成员一定要在前边加this指针
extendedChain(int initialCapacity = 10):chain<T>(initialCapacity) {lastNode = this->firstNode;}
extendedChain(const extendedChain<T>& theList) : chain<T>(theList)
{
chainNode<T>* currentNode = this->firstNode;
lastNode = this->firstNode;
while (currentNode != NULL)
{
lastNode=currentNode;
currentNode = currentNode->next;
}
}
void erase(int theIndex) override;
void insert(int theIndex, const T& theElement) override;
void clear();
void push_back(const T& theElement);
// Q2
void setSize(int theSize);
// Q3
void set(int theIndex, const T& theElement);
// Q4
void removeRange(int fromIndex, int ToIndex);
// Q5
int lastIndexOf(const T& theElement);
// Q6
T& operator[](const int& theIndex);
// Q7
bool operator==(const extendedChain<T>& theRight);
// Q8
bool operator!=(const extendedChain<T>& theRight);
// Q9
bool operator<(const extendedChain<T>& theright);
bool operator>(const extendedChain<T>& theright);
void operator=(const extendedChain<T>& theright);
// Q10
void swap(extendedChain<T>& theright);
// Q13
void fromList(const arrayList<T>& theList);
arrayList<T> toList();
// Q14
void leftShift(const int& i);
// Q15
void reverse();
// Q23
void circularShift(const int shiftLength);
protected:
chainNode<T>* lastNode;
};
template <class T>
void extendedChain<T>::erase(int theIndex)
{
chain<T>::erase(theIndex);
// erase之后listsize已经减一了,所以这里不用再减了
if(theIndex == this->listSize)
{
chainNode<T>* currentNode = this->firstNode;
while(currentNode != NULL)
{
lastNode=currentNode;
currentNode = currentNode->next;
}
}
}
template <class T>
void extendedChain<T>::insert(int theIndex, const T& theElement)
{
chain<T>::insert(theIndex, theElement);
// 插入第一个值的时候firstNode的值被改变了,所以需要重新赋值
if(this->listSize==1) lastNode=this->firstNode;
// 这里listsize又加了1
// 这里的条件需要注意,很容易忽略第二个条件
if((theIndex == this->listSize-1)&&(this->listSize-1>0))
lastNode = lastNode->next;
}
template <class T>
void extendedChain<T>::clear()
{
chainNode<T>* nextNode, *currentNode=this->firstNode;
while(currentNode != NULL)
{
nextNode = currentNode->next;
delete currentNode;
currentNode = nextNode;
}
this->listSize=0; // 清空保存个数
lastNode=this->firstNode;
}
template <class T>
void extendedChain<T>::push_back(const T& theElement)
{
// 利用lastNode指针来加快速度
if(this->listSize==0)
{
this->firstNode = new chainNode<T>(theElement, NULL);
lastNode = this->firstNode;
}
else
{
lastNode->next=new chainNode<T>(theElement, NULL);
lastNode = lastNode->next;
}
this->listSize++;
}
template <class T>
std::ostream& operator<<(std::ostream& out, extendedChain<T>& theList)
{
theList.output(out);
return out;
}
template <class T>
void extendedChain<T>::setSize(int theSize)
{
if(theSize < this->listSize)
{
while(this->listSize>theSize)
erase(this->listSize-1);
}
}
template <class T>
void extendedChain<T>::set(int theIndex, const T& theElement)
{
chainNode<T>* currentNode = this->firstNode;
for(int i=0;i<theIndex;i++)
currentNode=currentNode->next;
currentNode->element=theElement;
}
// 不删除索引为toIndex的元素
template <class T>
void extendedChain<T>::removeRange(int fromIndex, int toIndex)
{
// 直接调用erase函数会使得程序时间复杂度过高
this->checkIndex(fromIndex);
// 因为不删除最后一个元素, 所以可以和listSize相等,但检查时要减一
this->checkIndex(toIndex-1);
bool ifLastChange = false;
if(toIndex == this->listSize) ifLastChange=true;
chainNode<T>* fromNode = this->firstNode, *currentNode=NULL, *deleteNode=this->firstNode;
// 这里i=1是为了能够获得第一个被删除指针的前一个对象
if(fromIndex != 0)
{
for(int i=1; i<fromIndex;i++)
fromNode=fromNode->next;
deleteNode=fromNode->next;
}
currentNode=deleteNode;
for(int i=fromIndex;i<toIndex;i++)
{
currentNode=deleteNode->next;
delete deleteNode;
deleteNode = currentNode;
this->listSize--;
}
if(fromIndex==0)
this->firstNode=currentNode;
else
fromNode->next=currentNode;
// 看最后一个元素是否被删除
if(ifLastChange==true)
lastNode=fromNode;
}
template <class T>
int extendedChain<T>::lastIndexOf(const T& theElement)
{
int i=0, index = -1;
for(chainNode<T>* currentNode = this->firstNode; currentNode != NULL; currentNode=currentNode->next)
{
if(currentNode->element == theElement)
index=i;
i++;
}
return index;
}
template <class T>
T& extendedChain<T>::operator[](const int& theIndex)
{
return this->get(theIndex);
}
template <class T>
bool extendedChain<T>::operator==(const extendedChain<T>& theRight)
{
bool value = false;
if(this->listSize == theRight.listSize)
{
chainNode<T>* currentNodeR = theRight.firstNode;
for(chainNode<T>* currentNodeL = this->firstNode; currentNodeL != NULL; currentNodeL=currentNodeL->next)
{
if(currentNodeL->element != currentNodeR->element)
break;
currentNodeR=currentNodeR->next;
}
if(currentNodeR == NULL)
value=true;
}
return value;
}
template <class T>
bool extendedChain<T>::operator!=(const extendedChain<T>& theRight)
{
return !(*this == theRight);
}
template <class T>
bool extendedChain<T>::operator<(const extendedChain<T>& theRight)
{
chainNode<T>* currentNodeL = this->firstNode, *currentNodeR = theRight.firstNode;
int bothSize = std::min(this->listSize, theRight.listSize);
for(int i=0; i<bothSize;i++)
{
if(currentNodeL->element < currentNodeR->element)
return true;
else if(currentNodeL->element > currentNodeR->element)
return false;
}
// 如果共同长度的元素全部相等,比较长度
if(this->listSize < theRight.listSize)
return true;
else
return false;
}
template <class T>
bool extendedChain<T>::operator>(const extendedChain<T>& theRight)
{
chainNode<T>* currentNodeL = this->firstNode, *currentNodeR = theRight.firstNode;
int bothSize = std::min(this->listSize, theRight.listSize);
for(int i=0; i<bothSize;i++)
{
if(currentNodeL->element > currentNodeR->element)
return true;
else if(currentNodeL->element < currentNodeR->element)
return false;
currentNodeR=currentNodeR->next;
currentNodeL=currentNodeL->next;
}
// 如果共同长度的元素全部相等,比较长度
if(this->listSize > theRight.listSize)
return true;
else
return false;
}
template <class T>
void extendedChain<T>::operator=(const extendedChain<T>& theright)
{
this->clear();
this->listSize = theright.listSize;
if(this->listSize == 0)
{
this->firstNode=NULL;
return;
}
// if the theChain is not empty
chainNode<T>* sourceNode = theright.firstNode;
this->firstNode = new chainNode<T>(sourceNode->element); // 复制一个源链表的数据,并生成他的指针赋给头指针
sourceNode = sourceNode->next;
chainNode<T>* targetNode = this->firstNode;
while(sourceNode != NULL)
{
targetNode->next = new chainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = NULL;
chainNode<T>* currentNode = this->firstNode;
lastNode = this->firstNode;
while (currentNode != NULL)
{
lastNode=currentNode;
currentNode = currentNode->next;
}
}
template <class T>
void extendedChain<T>::swap(extendedChain<T>& theright)
{
int tmpSize = this->listSize;
chainNode<T>* tmpFirst = this->firstNode, *tmpLast = this->lastNode;
this->listSize=theright.listSize;
this->lastNode=theright.lastNode;
this->firstNode=theright.firstNode;
theright.listSize=tmpSize;
theright.firstNode=tmpFirst;
theright.lastNode=tmpLast;
}
// Q11
// 这里这种赋值方法需要重载=运算符
template <class T>
extendedChain<T> array2chain(const arrayList<T>& fromArray)
{
extendedChain<T> tmpExtendChain;
for(int i=0;i<fromArray.size();i++)
{
T& tmp = fromArray.get(i);
tmpExtendChain.insert(i, tmp);
}
return tmpExtendChain;
}
// Q12
template <class T>
arrayList<T> chain2array(const extendedChain<T>& fromList)
{
arrayList<T> tmpArray;
// chainNode<T>* currentNode = fromList.firstNode; // 是保护成员,不能使用,使用迭代器指针
typename chain<T>::myIterator chainStart = fromList.begin(), chainEnd = fromList.end();
for(int i=0; i<fromList.size(); i++)
{
tmpArray.insert(i, *chainStart);
chainStart++;
}
return tmpArray;
}
template <class T>
void extendedChain<T>::fromList(const arrayList<T>& theList)
{
this->clear();
for(int i=0;i<theList.size();i++)
{
T& tmp = theList.get(i);
push_back(tmp);
}
}
template <class T>
arrayList<T> extendedChain<T>::toList()
{
arrayList<T> tmpArray;
typename chain<T>::myIterator chainStart = this->begin(), chainEnd = this->end();
for(int i=0; i<this->size(); i++)
{
tmpArray.insert(i, *chainStart);
chainStart++;
}
return tmpArray;
}
template <class T>
void extendedChain<T>::leftShift(const int& length)
{
this->checkIndex(length-1);
for(int i=0; i<length; i++)
erase(0);
}
// 原地翻转,两个指针循环迭代
template <class T>
void extendedChain<T>::reverse()
{
chainNode<T>* aNode = this->firstNode, *bNode = aNode->next, *cNode = NULL;
aNode->next=NULL; // 首节点变为末节点,下一个为空
while(bNode != NULL)
{
cNode=bNode->next;
bNode->next=aNode;
aNode=bNode;
bNode=cNode;
}
lastNode = this->firstNode;
this->firstNode=aNode;
}
// Q17
template <class T>
extendedChain<T> meld(const extendedChain<T>& leftChain, const extendedChain<T>& rightChain)
{
extendedChain<T> tmp;
typename chain<T>::myIterator leftIterator = leftChain.begin(), rightIterator = rightChain.begin();
int shareSize = std::min(leftChain.size(), rightChain.size());
for(int i=0; i<shareSize; i++)
{
tmp.push_back(*leftIterator++);
tmp.push_back(*rightIterator++);
// leftIterator++;
// rightIterator++;
}
if(leftChain.size() < rightChain.size())
while(rightIterator != NULL)
tmp.push_back(*rightIterator++);
else
while(leftIterator != NULL)
tmp.push_back(*leftIterator++);
return tmp;
}
template <class T>
extendedChain<T> merge(const extendedChain<T>& leftChain, const extendedChain<T>& rightChain)
{
extendedChain<T> tmp;
typename extendedChain<T>::myIterator leftIter = leftChain.begin(), rightIter = rightChain.begin();
while(leftIter!=NULL && rightIter!=NULL)
{
if(*leftIter<*rightIter)
tmp.push_back(*leftIter++);
else
tmp.push_back(*rightIter++);
}
typename extendedChain<T>::myIterator extraIter = (leftIter==NULL) ? rightIter : leftIter;
while(extraIter!=NULL)
tmp.push_back(*extraIter++);
return tmp;
}
// Q21
template <class T>
void split(extendedChain<T>& fromChain, extendedChain<T>& leftChain, extendedChain<T>& rightChain)
{
leftChain.clear();
rightChain.clear();
typename chain<T>::myIterator fromIter = fromChain.begin(), endIter = fromChain.end();
while (fromIter != NULL)
{
leftChain.push_back(*fromIter++);
if(fromIter == NULL)
break;
rightChain.push_back(*fromIter++);
}
}
template <class T>
void extendedChain<T>::circularShift(const int shiftLength)
{
for(int i=0;i<shiftLength;i++)
{
lastNode->next = this->firstNode;
lastNode=lastNode->next;
this->firstNode = this->firstNode->next;
lastNode->next = NULL;
}
}
#endif
3、doubleLinkedList.h
#ifndef DOUBLELINKEDLIST_HPP
#define DOUBLELINKEDLIST_HPP
#include "linearList.h"
#include <iostream>
#include <algorithm>
#include <sstream>
template <class T>
struct doubleChainNode
{
// data member
T element;
doubleChainNode<T>* next, * previous;
// function
doubleChainNode() {}
doubleChainNode(const T& element) {this->element=element;}
doubleChainNode(const T& element, doubleChainNode<T>* previous, doubleChainNode<T>* next) {this->element=element;this->previous = previous;this->next=next;}
};
template <class T>
class doubleLinkedList : public linearList<T>
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const doubleLinkedList<U>& x);
public:
doubleLinkedList(int initialCapacity = 10);
doubleLinkedList(const doubleLinkedList<T>& theChain);
~doubleLinkedList();
bool empty() const {return listSize == 0;} // 调用STL库的方法
int size() const {return listSize;} // STL
T& get(int theIndex) const override;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(std::ostream &out) const;
void clear();
// Q39
void reverse();
// Q40
void meld(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain);
// Q41
void merge(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain);
// Q45
void appendChain(doubleLinkedList<T>& rightChain);
// Q48
void split(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain);
protected:
void checkIndex(int theIndex) const;
doubleChainNode<T>* firstNode, * lastNode; // 指向链表第一个节点的指针
int listSize; // 当前链表的长度
};
template <class T>
doubleLinkedList<T>::doubleLinkedList(int initialCapacity)
{
if(initialCapacity < 1)
{
std::ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
}
firstNode = NULL;
lastNode = NULL;
listSize = 0;
}
template <class T>
doubleLinkedList<T>::doubleLinkedList(const doubleLinkedList<T>& theChain)
{
listSize = theChain.listSize;
if(listSize == 0)
{
firstNode = NULL;
lastNode = NULL;
return;
}
doubleChainNode<T>* sourceNode = theChain.firstNode;
firstNode = new doubleChainNode<T>(sourceNode->element, NULL, NULL);
lastNode = firstNode;
doubleChainNode<T>* targetNode = firstNode, * preNode = NULL;
sourceNode = sourceNode->next;
while(sourceNode != NULL)
{
targetNode->previous = preNode;
targetNode->next = new doubleChainNode<T>(sourceNode->element);
preNode = targetNode;
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->previous = preNode;
targetNode->next = NULL;
lastNode = targetNode;
}
template <class T>
doubleLinkedList<T>::~doubleLinkedList()
{
doubleChainNode<T>* nextNode;
while((listSize--)>0)
{
nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template <class T>
void doubleLinkedList<T>::checkIndex(int theIndex) const
{
if(theIndex >= listSize)
throw "theIndex is bigger than listSize!";
}
template <class T>
T& doubleLinkedList<T>::get(int theIndex) const
{
checkIndex(theIndex);
if(theIndex < listSize/2)
{
doubleChainNode<T>* currentNode = firstNode;
for(int i=0; i<theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
else
{
doubleChainNode<T>* currentNode = lastNode;
for(int i=0; i<listSize-1-theIndex; i++)
currentNode = currentNode->previous;
return currentNode->element;
}
}
template <class T>
int doubleLinkedList<T>::indexOf(const T& theElement) const
{
doubleChainNode<T>* currentNode = firstNode;
int theIndex = 0;
while(currentNode->element != theElement && currentNode != NULL)
{
currentNode = currentNode->next;
theIndex++;
}
if(currentNode == NULL)
return -1;
else
return theIndex;
}
template <class T>
void doubleLinkedList<T>::erase(int theIndex)
{
checkIndex(theIndex);
doubleChainNode<T>* currentNode = firstNode, *deleteNode = NULL, * preNode = NULL;
if(listSize == 1)
{
deleteNode = firstNode;
firstNode=NULL;
lastNode=NULL;
}
else if(theIndex == 0)
{
deleteNode = firstNode;
firstNode = firstNode->next;
firstNode->previous = NULL; // firsrNode的位置已经变过了
}
else
{
for(int i=0;i<theIndex;i++)
{
preNode = currentNode;
currentNode = currentNode->next;
}
deleteNode = currentNode;
if(theIndex == listSize-1)
{
preNode->next=NULL;
lastNode=preNode;
}
else
{
currentNode->next->previous = preNode;
preNode->next = currentNode->next;
}
}
delete deleteNode;
listSize--;
}
template <class T>
void doubleLinkedList<T>::insert(int theIndex, const T& theElement)
{
checkIndex(theIndex-1);
doubleChainNode<T>* currentNode = firstNode, * preNode = NULL;
if(listSize == 0)
{
firstNode = new doubleChainNode<T>(theElement, NULL, NULL);
lastNode = firstNode;
}
else if(theIndex == 0)
{
firstNode = new doubleChainNode<T>(theElement, NULL, firstNode);
firstNode->next->previous = firstNode;
}
else if(theIndex == listSize)
{
lastNode->next = new doubleChainNode<T>(theElement, lastNode, NULL);
lastNode = lastNode->next;
}
else
{
for(int i=0;i<theIndex;i++)
{
preNode = currentNode;
currentNode = currentNode->next;
}
preNode->next = new doubleChainNode<T>(theElement, preNode, currentNode);
currentNode->previous = preNode->next;
}
listSize++;
}
template <class T>
void doubleLinkedList<T>::clear()
{
for(int i = 0; i< listSize; i++)
erase(0);
firstNode = NULL;
lastNode = NULL;
listSize = 0;
}
template <class T>
void doubleLinkedList<T>::output(std::ostream &out) const
{
for(doubleChainNode<T>* currentNode=firstNode; currentNode != NULL; currentNode=currentNode->next)
out << currentNode->element << " ";
}
template <class U>
std::ostream& operator<<(std::ostream& out, const doubleLinkedList<U>& theList)
{
theList.output(out);
return out;
}
template <class T>
void doubleLinkedList<T>::appendChain(doubleLinkedList<T>& rightChain)
{
lastNode->next = rightChain.firstNode;
rightChain.firstNode->previous = lastNode;
lastNode = rightChain.lastNode;
listSize += rightChain.listSize;
rightChain.lastNode = NULL;
rightChain.firstNode = NULL;
rightChain.listSize = 0;
}
template <class T>
void doubleLinkedList<T>::reverse()
{
doubleChainNode<T>* currentNode = firstNode, * tmpNode;
while(currentNode!=NULL)
{
tmpNode = currentNode->next;
currentNode->next = currentNode->previous;
currentNode->previous = tmpNode;
currentNode = tmpNode;
}
tmpNode = firstNode;
firstNode = lastNode;
lastNode = tmpNode;
}
template <class T>
void doubleLinkedList<T>::meld(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain)
{
clear();
doubleChainNode<T>* currentNode = NULL, *leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode;
int shareSize = std::min(leftChain.size(), rightChain.size());
for(int i=0; i<shareSize; i++)
{
if(i==0)
currentNode = leftNode;
else
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
currentNode = currentNode->next;
}
leftNode = leftNode->next;
rightNode->previous = currentNode;
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
}
if(leftChain.size() > rightChain.size())
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
lastNode = leftChain.lastNode;
}
else
// 因为上边的for循环最后就是链接到rightchain的
// 所以省略了一些步骤
lastNode = rightChain.lastNode;
if(leftChain.size() != 0)
firstNode = leftChain.firstNode;
else
firstNode = rightChain.firstNode;
listSize = leftChain.size() + rightChain.size();
rightChain.lastNode = NULL; rightChain.firstNode = NULL; rightChain.listSize = 0;
leftChain.lastNode = NULL; leftChain.firstNode = NULL; leftChain.listSize = 0;
}
template <class T>
void doubleLinkedList<T>::merge(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain)
{
clear();
doubleChainNode<T>* leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode, *currentNode = NULL;
if(leftNode->element < rightNode->element)
{
currentNode = leftNode;
leftNode = leftNode->next;
}
else
{
currentNode = rightNode;
rightNode = rightNode->next;
}
firstNode = currentNode; // 更新当前对象的头指针
while(leftNode != NULL && rightNode != NULL)
{
if(leftNode->element < rightNode->element)
{
currentNode->next = leftNode;
leftNode->previous = currentNode;
currentNode = currentNode->next;
leftNode = leftNode->next;
}
else
{
currentNode->next = rightNode;
rightNode->previous = currentNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
}
}
doubleChainNode<T>* extraNode = (leftNode == NULL) ? rightNode : leftNode;
currentNode->next = extraNode;
extraNode->previous = currentNode;
lastNode = (leftNode == NULL) ? rightChain.lastNode : leftChain.lastNode;
listSize = leftChain.size() + rightChain.size();
rightChain.lastNode = NULL; rightChain.firstNode = NULL; rightChain.listSize = 0;
leftChain.lastNode = NULL; leftChain.firstNode = NULL; leftChain.listSize = 0;
}
template <class T>
void doubleLinkedList<T>::split(doubleLinkedList<T>& leftChain, doubleLinkedList<T>& rightChain)
{
leftChain.clear();
rightChain.clear();
doubleChainNode<T>* currentNode = firstNode;
while (currentNode != NULL)
{
leftChain.insert(leftChain.size(), currentNode->element);
currentNode = currentNode->next;
if(currentNode == NULL)
break;
rightChain.insert(rightChain.size(), currentNode->element);
currentNode = currentNode->next;
}
}
#endif
4、doubleCircleList.h
#ifndef DOUBLECIRCULARLIST_HPP
#define DOUBLECIRCULARLIST_HPP
#include "doubleLinkedList.hpp"
#include "linearList.h"
#include <iostream>
#include <algorithm>
#include <sstream>
template <class T>
class doubleCircularList : public linearList<T>
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const doubleLinkedList<U>& x);
public:
doubleCircularList(int initialCapacity = 10);
doubleCircularList(const doubleCircularList<T>& theChain);
~doubleCircularList();
bool empty() const {return listSize == 0;} // 调用STL库的方法
int size() const {return listSize;} // STL
T& get(int theIndex) const override;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(std::ostream &out) const;
void clear();
// Q39
void reverse();
// Q40
void meld(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain);
// Q41
void merge(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain);
// Q48
void split(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain);
protected:
void checkIndex(int theIndex) const;
doubleChainNode<T>* firstNode; // 指向链表第一个节点的指针
int listSize; // 当前链表的长度
};
template <class T>
doubleCircularList<T>::doubleCircularList(int initialCapacity)
{
if(initialCapacity < 1)
{
std::ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
}
firstNode = NULL;
listSize = 0;
}
template <class T>
doubleCircularList<T>::doubleCircularList(const doubleCircularList<T>& theChain)
{
listSize = theChain.listSize;
if(listSize == 0)
{
firstNode = NULL;
return;
}
doubleChainNode<T>* sourceNode = theChain.firstNode;
firstNode = new doubleChainNode<T>(sourceNode->element, NULL, NULL);
firstNode->next = firstNode;
firstNode->previous = firstNode;
doubleChainNode<T>* targetNode = firstNode;
sourceNode = sourceNode->next;
while(sourceNode != theChain.firstNode)
{
targetNode->next = new doubleChainNode<T>(sourceNode->element, targetNode, firstNode);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
firstNode->previous = targetNode;
}
}
template <class T>
doubleCircularList<T>::~doubleCircularList()
{
doubleChainNode<T>* nextNode;
while((listSize--)>0)
{
nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template <class T>
void doubleCircularList<T>::checkIndex(int theIndex) const
{
if(theIndex >= listSize)
throw "theIndex is bigger than listSize!";
}
template <class T>
T& doubleCircularList<T>::get(int theIndex) const
{
checkIndex(theIndex);
if(theIndex < listSize/2)
{
doubleChainNode<T>* currentNode = firstNode;
for(int i=0; i<theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
else
{
doubleChainNode<T>* currentNode = firstNode->previous;
for(int i=0; i<listSize-1-theIndex; i++)
currentNode = currentNode->previous;
return currentNode->element;
}
}
template <class T>
int doubleCircularList<T>::indexOf(const T& theElement) const
{
doubleChainNode<T>* currentNode = firstNode;
int theIndex = 0;
while(currentNode->element != theElement && theIndex < listSize)
{
currentNode = currentNode->next;
theIndex++;
}
if(theIndex == listSize)
return -1;
else
return theIndex;
}
template <class T>
void doubleCircularList<T>::erase(int theIndex)
{
checkIndex(theIndex);
doubleChainNode<T>* currentNode = firstNode, *deleteNode = NULL, * preNode = NULL;
// if(listSize == 1)
// {
// deleteNode = firstNode;
// firstNode=NULL;
// }
if(theIndex == 0)
{
deleteNode = firstNode;
firstNode->next->previous = firstNode->previous;
firstNode->previous->next = firstNode->next;
firstNode = firstNode->next;
}
else
{
for(int i=0;i<theIndex;i++)
currentNode = currentNode->next;
deleteNode = currentNode;
currentNode->previous->next = currentNode->next;
currentNode->next->previous = currentNode->previous;
}
delete deleteNode;
listSize--;
}
template <class T>
void doubleCircularList<T>::insert(int theIndex, const T& theElement)
{
checkIndex(theIndex-1);
if(listSize == 0)
{
firstNode = new doubleChainNode<T>(theElement, NULL, NULL);
firstNode->next = firstNode;
firstNode->previous = firstNode;
}
else if(theIndex == 0)
{
firstNode = new doubleChainNode<T>(theElement, firstNode->previous, firstNode);
firstNode->next->previous = firstNode;
firstNode->previous->next = firstNode;
}
else
{
doubleChainNode<T>* currentNode = firstNode;
for(int i=0;i<theIndex;i++)
currentNode = currentNode->next;
currentNode->previous->next = new doubleChainNode<T>(theElement, currentNode->previous, currentNode);
currentNode->previous = currentNode->previous->next;
}
listSize++;
}
template <class T>
void doubleCircularList<T>::clear()
{
for(int i = 0; i< listSize; i++)
erase(0);
firstNode = NULL;
listSize = 0;
}
template <class T>
void doubleCircularList<T>::output(std::ostream &out) const
{
int i=0;
for(doubleChainNode<T>* currentNode=firstNode; i<listSize; currentNode=currentNode->next, i++)
out << currentNode->element << " ";
}
template <class U>
std::ostream& operator<<(std::ostream& out, const doubleCircularList<U>& theList)
{
theList.output(out);
return out;
}
template <class T>
void doubleCircularList<T>::reverse()
{
doubleChainNode<T>* currentNode = firstNode, * tmpNode;
for(int i=0; i<listSize; i++)
{
tmpNode = currentNode->next;
currentNode->next = currentNode->previous;
currentNode->previous = tmpNode;
currentNode = tmpNode;
}
}
// 两个输入都必须至少有一个元素
template <class T>
void doubleCircularList<T>::meld(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain)
{
clear();
doubleChainNode<T>* currentNode = NULL, *leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode;
doubleChainNode<T>* leftLastNode = leftNode->previous, * rightLastNode = rightNode->previous;
int shareSize = std::min(leftChain.size(), rightChain.size());
for(int i=0; i<shareSize; i++)
{
if(i==0)
{
currentNode = leftNode;
leftNode = leftNode->next;
firstNode = currentNode;
currentNode->previous = currentNode;
currentNode->next = currentNode;
}
else
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftNode = leftNode->next;
currentNode = currentNode->next;
currentNode->next = firstNode;
firstNode->previous = currentNode;
}
rightNode->previous = currentNode;
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
currentNode->next = firstNode;
firstNode->previous = currentNode;
}
if(leftChain.size() > rightChain.size())
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftLastNode->next = firstNode;
firstNode->previous = leftLastNode;
}
else
{
// 因为上边的for循环最后就是链接到rightchain的
// 所以省略了一些步骤
rightLastNode->next = firstNode;
firstNode->previous = rightLastNode;
}
listSize = leftChain.size() + rightChain.size();
leftChain.firstNode = NULL; leftChain.listSize = 0;
rightChain.firstNode = NULL; rightChain.listSize = 0;
}
template <class T>
void doubleCircularList<T>::merge(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain)
{
clear();
doubleChainNode<T>* currentNode = NULL, *leftNode = leftChain.firstNode, *rightNode = rightChain.firstNode;
doubleChainNode<T>* leftLastNode = leftNode->previous, * rightLastNode = rightNode->previous;
int leftCount = leftChain.size(), rightCount = rightChain.size();
if(leftNode->element < rightNode->element)
{
currentNode = leftNode;
leftNode = leftNode->next;
leftCount--;
}
else
{
currentNode = rightNode;
rightNode = rightNode->next;
rightCount--;
}
firstNode = currentNode; // 更新当前对象的头指针
firstNode->next = firstNode;
firstNode->previous = firstNode;
while(leftCount != 0 && rightCount != 0)
{
if(leftNode->element < rightNode->element)
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftNode = leftNode->next;
currentNode = currentNode->next;
currentNode->next = firstNode;
firstNode->previous = currentNode;
leftCount--;
}
else
{
rightNode->previous = currentNode;
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
currentNode->next = firstNode;
firstNode->previous = currentNode;
rightCount--;
}
}
doubleChainNode<T>* extraNode = (leftCount == 0) ? rightNode : leftNode;
doubleChainNode<T>* extraLast = (leftCount == 0) ? rightLastNode : leftLastNode;
currentNode->next = extraNode;
extraNode->previous = currentNode;
firstNode->previous = extraLast;
extraLast->next = firstNode;
listSize = leftChain.size() + rightChain.size();
rightChain.firstNode = NULL; rightChain.listSize = 0;
leftChain.firstNode = NULL; leftChain.listSize = 0;
}
template <class T>
void doubleCircularList<T>::split(doubleCircularList<T>& leftChain, doubleCircularList<T>& rightChain)
{
leftChain.clear();
rightChain.clear();
doubleChainNode<T>* currentNode = firstNode;
for(int i=0; i<listSize;)
{
leftChain.insert(leftChain.size(), currentNode->element);
currentNode = currentNode->next;
i++;
if(i == listSize)
break;
rightChain.insert(rightChain.size(), currentNode->element);
currentNode = currentNode->next;
i++;
}
}
#endif
5、circleListWithHeader.h
#ifndef CIRCULARLISTWITHHEADER
#define CIRCULARLISTWITHHEADER
#include "chain.h"
#include "linearList.h"
#include <iostream>
#include <algorithm>
#include <sstream>
template <class T>
class circularListWithHeader : public linearList<T>
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const circularListWithHeader<U>& x);
public:
circularListWithHeader(int initialCapacity = 10);
circularListWithHeader(const circularListWithHeader<T>& theChain);
~circularListWithHeader();
bool empty() const {return listSize == 0;} // 调用STL库的方法
int size() const {return listSize;} // STL
T& get(int theIndex) const override;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(std::ostream &out) const;
// Q39
void reverse();
// Q40
void meld(circularListWithHeader<T>& leftChain, circularListWithHeader<T>& rightChain);
// Q41
void merge(circularListWithHeader<T>& leftChain, circularListWithHeader<T>& rightChain);
protected:
void checkIndex(int theIndex) const;
chainNode<T>* headerNode; // 指向链表第一个节点的指针
int listSize; // 当前链表的长度
};
template <class T>
circularListWithHeader<T>::circularListWithHeader(int initialCapacity)
{
if(initialCapacity < 1)
{
std::ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
}
headerNode = new chainNode<T>();
headerNode->next = headerNode;
listSize = 0;
}
template <class T>
circularListWithHeader<T>::circularListWithHeader(const circularListWithHeader<T>& theChain)
{
listSize = theChain.listSize;
headerNode = new chainNode<T>();
if(listSize == 0)
{
headerNode->next = headerNode;
return;
}
chainNode<T>* sourceNode = theChain.headerNode;
chainNode<T>* targetNode = headerNode;
while(sourceNode != NULL)
{
targetNode->next = new chainNode<T>(sourceNode->element);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
}
targetNode->next = headerNode;
}
template <class T>
circularListWithHeader<T>::~circularListWithHeader()
{
chainNode<T>* nextNode;
while((listSize--)>=0)
{
nextNode = headerNode->next;
delete headerNode;
headerNode = nextNode;
}
}
template <class T>
void circularListWithHeader<T>::checkIndex(int theIndex) const
{
if(theIndex >= listSize)
throw "theIndex is bigger than listSize!";
}
template <class T>
T& circularListWithHeader<T>::get(int theIndex) const
{
checkIndex(theIndex);
chainNode<T>* currentNode = headerNode->next;
for(int i=0; i<theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
template <class T>
int circularListWithHeader<T>::indexOf(const T& theElement) const
{
chainNode<T>* currentNode = headerNode->next;
int theIndex = 0;
while(currentNode->element != theElement && currentNode != headerNode)
{
currentNode = currentNode->next;
theIndex++;
}
if(currentNode == headerNode)
return -1;
else
return theIndex;
}
template <class T>
void circularListWithHeader<T>::erase(int theIndex)
{
checkIndex(theIndex);
chainNode<T>* currentNode = headerNode->next, *preNode = headerNode;
for(int i=0; i<theIndex; i++)
{
preNode = currentNode;
currentNode = currentNode->next;
}
chainNode<T>* deleteNode = currentNode;
preNode->next = currentNode->next;
delete deleteNode;
listSize--;
}
template <class T>
void circularListWithHeader<T>::insert(int theIndex, const T& theElement)
{
checkIndex(theIndex-1);
chainNode<T>* currentNode = headerNode->next, *preNode = headerNode;
for(int i=0; i<theIndex; i++)
{
preNode = currentNode;
currentNode = currentNode->next;
}
preNode->next = new chainNode<T>(theElement, currentNode);
listSize++;
}
template <class T>
void circularListWithHeader<T>::output(std::ostream &out) const
{
for(chainNode<T>* currentNode=headerNode->next; currentNode != headerNode; currentNode=currentNode->next)
out << currentNode->element << " ";
}
template <class U>
std::ostream& operator<<(std::ostream& out, const circularListWithHeader<U>& theList)
{
theList.output(out);
return out;
}
template <class T>
void circularListWithHeader<T>::reverse()
{
chainNode<T>* preNode = headerNode, *currentNode = headerNode->next, *nextNode = currentNode->next;
// 因为还有头节点,所以需要加1
for(int i=0;i<listSize+1;i++)
{
currentNode->next = preNode;
preNode = currentNode;
currentNode = nextNode;
nextNode = currentNode->next;
}
}
template <class T>
void circularListWithHeader<T>::meld(circularListWithHeader<T>& leftChain, circularListWithHeader<T>& rightChain)
{
for(int i=0; i<listSize; i++)
erase(0);
chainNode<T>* currentNode = headerNode, *leftNode = leftChain.headerNode->next, *rightNode = rightChain.headerNode->next;
int shareSize = std::min(leftChain.size(), rightChain.size());
for(int i=0; i<shareSize; i++)
{
currentNode->next=leftNode;
currentNode=currentNode->next;
leftNode=leftNode->next;
currentNode->next = rightNode;
rightNode=rightNode->next;
currentNode = currentNode->next;
}
if(leftChain.size() > rightChain.size())
{
while(leftNode != leftChain.headerNode)
{
currentNode->next = leftNode;
leftNode = leftNode->next;
currentNode = currentNode->next;
}
}
else
{
while(rightNode != rightChain.headerNode)
{
currentNode->next = rightNode;
rightNode = rightNode->next;
currentNode = currentNode->next;
}
}
currentNode->next = headerNode;
listSize = leftChain.size() + rightChain.size();
leftChain.headerNode->next=leftChain.headerNode;
rightChain.headerNode->next=rightChain.headerNode;
leftChain.listSize=0;
rightChain.listSize=0;
}
template <class T>
void circularListWithHeader<T>::merge(circularListWithHeader<T>& leftChain, circularListWithHeader<T>& rightChain)
{
for(int i=0; i<listSize; i++)
erase(0);
chainNode<T>* currentNode = headerNode, *leftNode = leftChain.headerNode->next, *rightNode = rightChain.headerNode->next;
while(leftNode != leftChain.headerNode && rightNode != rightChain.headerNode)
{
if(leftNode->element < rightNode->element)
{
currentNode->next = leftNode;
currentNode = currentNode->next;
leftNode = leftNode->next;
}
else
{
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
}
}
chainNode<T>* extraNode = (leftNode == leftChain.headerNode) ? rightNode : leftNode;
chainNode<T>* theHeader = (leftNode == leftChain.headerNode) ? rightChain.headerNode : leftChain.headerNode;
while(extraNode != theHeader)
{
currentNode->next = extraNode;
currentNode = currentNode->next;
extraNode = extraNode->next;
}
currentNode->next = headerNode;
listSize = leftChain.size() + rightChain.size();
leftChain.headerNode->next=leftChain.headerNode;
rightChain.headerNode->next=rightChain.headerNode;
leftChain.listSize=0;
rightChain.listSize=0;
}
#endif
6、doubleCircularListWithHeader.h
#ifndef DOUBLECIRCULARLISTWITHHEADER_HPP
#define DOUBLECIRCULARLISTWITHHEADER_HPP
#include "doubleLinkedList.hpp"
#include "linearList.h"
#include <iostream>
#include <algorithm>
#include <sstream>
template <class T>
class doubleCircularListWithHeader : public linearList<T>
{
template <class U>
friend std::ostream& operator<<(std::ostream& out, const doubleCircularListWithHeader<U>& x);
public:
doubleCircularListWithHeader(int initialCapacity = 10);
doubleCircularListWithHeader(const doubleCircularListWithHeader<T>& theChain);
~doubleCircularListWithHeader();
bool empty() const {return listSize == 0;} // 调用STL库的方法
int size() const {return listSize;} // STL
T& get(int theIndex) const override;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(std::ostream &out) const;
void clear();
void push_back(const T& theElement);
// Q39
void reverse();
// Q40
void meld(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain);
// Q41
void merge(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain);
// Q48
void split(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain);
class myIterator
{
// 构造函数
myIterator(doubleChainNode<T>* theNode = NULL) {node = theNode;}
// 解引用操作符
T& operator*() const {return node->element;}
T* operator->() const {return &node->element;}
// 单向列表,只能递加操作,无递减操作
myIterator& operator++() {node = node->next; return *this;} // 先改变自身,然后返回一个指针
myIterator operator++(int) {myIterator p=*this; node = node->next;return p;} // 这里关于指针类型的问题很重要
myIterator& operator--() {node = node->previous; return *this;}
myIterator operator--(int) {myIterator p=*this; node = node->previous;return p;}
// 相等检验
bool operator==(const myIterator& right) const {return node == right.node;}
bool operator!=(const myIterator& right) const {return node != right.node;}
protected:
doubleChainNode<T>* node;
};
myIterator begin() const {return myIterator(headerNode->next);}
myIterator end() const {return myIterator(headerNode);}
protected:
void checkIndex(int theIndex) const;
doubleChainNode<T>* headerNode; // 指向链表第一个节点的指针
int listSize; // 当前链表的长度
};
template <class T>
doubleCircularListWithHeader<T>::doubleCircularListWithHeader(int initialCapacity)
{
if(initialCapacity < 1)
{
std::ostringstream s;
s << "Initial capacity = " << initialCapacity << " Must be > 0";
}
headerNode = new doubleChainNode<T>();
headerNode->next = headerNode;
headerNode->previous = headerNode;
listSize = 0;
}
template <class T>
doubleCircularListWithHeader<T>::doubleCircularListWithHeader(const doubleCircularListWithHeader<T>& theChain)
{
listSize = theChain.listSize;
headerNode = new doubleChainNode<T>();
headerNode->next = headerNode;
headerNode->previous = headerNode;
if(listSize == 0)
return;
doubleChainNode<T>* sourceNode = theChain.headerNode->next;
doubleChainNode<T>* targetNode = headerNode;
while(sourceNode != theChain.headerNode)
{
targetNode->next = new doubleChainNode<T>(sourceNode->element, targetNode, headerNode);
targetNode = targetNode->next;
sourceNode = sourceNode->next;
headerNode->previous = targetNode;
}
}
template <class T>
doubleCircularListWithHeader<T>::~doubleCircularListWithHeader()
{
doubleChainNode<T>* nextNode;
while((listSize--)>=0)
{
nextNode = headerNode->next;
delete headerNode;
headerNode = nextNode;
}
}
template <class T>
void doubleCircularListWithHeader<T>::checkIndex(int theIndex) const
{
if(theIndex >= listSize)
throw "theIndex is bigger than listSize!";
}
template <class T>
T& doubleCircularListWithHeader<T>::get(int theIndex) const
{
checkIndex(theIndex);
if(theIndex < listSize/2)
{
doubleChainNode<T>* currentNode = headerNode->next;
for(int i=0; i<theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
else
{
doubleChainNode<T>* currentNode = headerNode->previous;
for(int i=0; i<listSize-1-theIndex; i++)
currentNode = currentNode->previous;
return currentNode->element;
}
}
template <class T>
int doubleCircularListWithHeader<T>::indexOf(const T& theElement) const
{
doubleChainNode<T>* currentNode = headerNode->next;
int theIndex = 0;
while(currentNode->element != theElement && theIndex < listSize)
{
currentNode = currentNode->next;
theIndex++;
}
if(theIndex == listSize)
return -1;
else
return theIndex;
}
template <class T>
void doubleCircularListWithHeader<T>::erase(int theIndex)
{
checkIndex(theIndex);
doubleChainNode<T>* currentNode = headerNode->next, *deleteNode = NULL, * preNode = NULL;
for(int i=0;i<theIndex;i++)
currentNode = currentNode->next;
deleteNode = currentNode;
currentNode->previous->next = currentNode->next;
currentNode->next->previous = currentNode->previous;
delete deleteNode;
listSize--;
}
template <class T>
void doubleCircularListWithHeader<T>::insert(int theIndex, const T& theElement)
{
checkIndex(theIndex-1);
doubleChainNode<T>* currentNode = headerNode;
for(int i=0;i<theIndex;i++)
currentNode = currentNode->next;
doubleChainNode<T>* nextNode = currentNode->next;
currentNode->next = new doubleChainNode<T>(theElement, currentNode, nextNode);
nextNode->previous = currentNode->next;
listSize++;
}
template <class T>
void doubleCircularListWithHeader<T>::push_back(const T& theElement)
{
doubleChainNode<T>* preNode = headerNode->previous;
headerNode->previous = new doubleChainNode<T>(theElement, preNode, headerNode);
preNode->next = headerNode->previous;
listSize++;
}
template <class T>
void doubleCircularListWithHeader<T>::clear()
{
// headerNode的指针自动复原
for(int i = 0; i< listSize; i++)
erase(0);
listSize = 0;
}
template <class T>
void doubleCircularListWithHeader<T>::output(std::ostream &out) const
{
int i=0;
for(doubleChainNode<T>* currentNode=headerNode->next; currentNode != headerNode; currentNode=currentNode->next)
out << currentNode->element << " ";
}
template <class U>
std::ostream& operator<<(std::ostream& out, const doubleCircularListWithHeader<U>& theList)
{
theList.output(out);
return out;
}
template <class T>
void doubleCircularListWithHeader<T>::reverse()
{
doubleChainNode<T>* currentNode = headerNode, * tmpNode;
// 多了一个头节点要置换
for(int i=0; i<listSize+1; i++)
{
tmpNode = currentNode->next;
currentNode->next = currentNode->previous;
currentNode->previous = tmpNode;
currentNode = tmpNode;
}
}
// 两个输入都必须至少有一个元素
template <class T>
void doubleCircularListWithHeader<T>::meld(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain)
{
clear();
doubleChainNode<T>* currentNode = headerNode, *leftNode = leftChain.headerNode->next, *rightNode = rightChain.headerNode->next;
doubleChainNode<T>* leftLastNode = leftChain.headerNode->previous, * rightLastNode = rightChain.headerNode->previous;
int shareSize = std::min(leftChain.size(), rightChain.size());
for(int i=0; i<shareSize; i++)
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftNode = leftNode->next;
currentNode = currentNode->next;
currentNode->next = headerNode;
headerNode->previous = currentNode;
rightNode->previous = currentNode;
currentNode->next = rightNode;
rightNode = rightNode->next;
currentNode = currentNode->next;
currentNode->next = headerNode;
headerNode->previous = currentNode;
}
if(leftChain.size() > rightChain.size())
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftLastNode->next = headerNode;
headerNode->previous = leftLastNode;
}
else if(leftChain.size() < rightChain.size())
{
rightNode->previous = currentNode;
currentNode->next = rightNode;
rightLastNode->next = headerNode;
headerNode->previous = rightLastNode;
}
listSize = leftChain.size() + rightChain.size();
leftChain.headerNode->next = leftChain.headerNode; leftChain.headerNode->previous = leftChain.headerNode; leftChain.listSize = 0;
rightChain.headerNode->next = rightChain.headerNode; rightChain.headerNode->previous = rightChain.headerNode; rightChain.listSize = 0;
}
template <class T>
void doubleCircularListWithHeader<T>::merge(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain)
{
clear();
doubleChainNode<T>* currentNode = headerNode, *leftNode = leftChain.headerNode->next, *rightNode = rightChain.headerNode->next;
doubleChainNode<T>* leftLastNode = leftChain.headerNode->previous, * rightLastNode = rightChain.headerNode->previous;
while(leftNode != leftChain.headerNode && rightNode != rightChain.headerNode)
{
if(leftNode->element < rightNode->element)
{
leftNode->previous = currentNode;
currentNode->next = leftNode;
leftNode = leftNode->next;
currentNode = currentNode->next;
currentNode->next = headerNode;
headerNode->previous = currentNode;
}
else
{
rightNode->previous = currentNode;
currentNode->next = rightNode;
currentNode = currentNode->next;
rightNode = rightNode->next;
currentNode->next = headerNode;
headerNode->previous = currentNode;
}
}
doubleChainNode<T>* extraNode = (leftNode == leftChain.headerNode) ? rightNode : leftNode;
doubleChainNode<T>* extraLast = (leftNode == leftChain.headerNode) ? rightLastNode : leftLastNode;
currentNode->next = extraNode;
extraNode->previous = currentNode;
headerNode->previous = extraLast;
extraLast->next = headerNode;
listSize = leftChain.size() + rightChain.size();
leftChain.headerNode->next = leftChain.headerNode; leftChain.headerNode->previous = leftChain.headerNode; leftChain.listSize = 0;
rightChain.headerNode->next = rightChain.headerNode; rightChain.headerNode->previous = rightChain.headerNode; rightChain.listSize = 0;
}
template <class T>
void doubleCircularListWithHeader<T>::split(doubleCircularListWithHeader<T>& leftChain, doubleCircularListWithHeader<T>& rightChain)
{
leftChain.clear();
rightChain.clear();
doubleChainNode<T>* currentNode = headerNode->next;
while(currentNode != headerNode)
{
// 这里可以采用更简单的方法
leftChain.push_back(currentNode->element);
currentNode = currentNode->next;
if(currentNode == headerNode)
break;
rightChain.push_back(currentNode->element);
currentNode = currentNode->next;
}
}
#endif

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)