第1关:实现链表结点
#include <iostream>
using namespace std;
template <class T>
class Node {
/********** Begin **********/
};
/********** End **********/
int main()
{
int a[10];
Node<int> n[10];
// cout << "输入10 个整数:" << endl;
for (int i = 0; i < 10; i ++) {
cin >> a[i];
}
for (int i = 0; i < 9; i ++) {
n[i].data = a[i];
n[i].insertAfter(&n[i+1]);
}
n[9].data = a[9];
Node<int>* np = &n[0];
while (np != NULL) {
cout << np->data << ' ';
np = np->nextNode();
}
cout << endl;
int f;
// cout << "请输入要查找的数:";
cin >> f;
Node<int> p(0, &n[0]);
np = &p;
while (np->nextNode() != NULL) {
while (np->nextNode() != NULL && np->nextNode()->data == f)
np->deleteAfter();
if(np->nextNode() != NULL)
np = np->nextNode();
}
// cout << "删除后的链表:" << endl;
np = p.nextNode();
while (np != NULL) {
cout << np->data << ' ';
np = np->nextNode();
}
np = &p;
while (np->nextNode() != NULL)
np->deleteAfter();
cout << endl;
return 0;
}
第2关:实现链表
#include <iostream>
template <class T>
class Node {
private:
T data;
public:
Node* next;
Node();
Node(const T& data, Node<T>* nt = 0);
// Node(T data, Node<T>* n = NULL);
T& getData();
};
template <class T>
Node<T>::Node() {
data = 0;
next = NULL;
}
template <class T>
Node<T>::Node(const T& d, Node<T>* nt) {
data = d;
next = nt;
}
template <class T>
T& Node<T>::getData() {
return data;
}
/********** Begin **********/
template <class T>
class LinkedList {
private:
Node<T> *front, *rear; //表头和表尾指针
Node<T> *prevPtr, *currPtr; //记录表当前遍历位置的指针,由插入和删除操作更新
int size; //表中元素个数
int position; //当前元素在表中的位置序号。由函数reset使用
Node<T>* newNode(const T& item, Node<T> *ptrNext = NULL); //生成新节点,数据与为item,指针域为prtNext
void freeNode(Node<T> *p); //释放节点
void copy(const LinkedList<T>& L); //将链表L复制到当前表(假设当前表为空),被复制构造函数和operator=调用
public:
LinkedList(); //构造函数
LinkedList(const LinkedList<T>& L); //复制构造函数
~LinkedList(); //析构函数
LinkedList<T>& operator = (const LinkedList<T>& L); //重载赋值运算符
int getSize() const; //返回链表中元素个数
bool isEmpty() const; //链表是否为空
void reset(int pos = 0); //初始化游标的位置
void next(); //使游标移动到下一个节点
bool endOfList() const; //游标是否移动到链尾
int currentPosition() const; //返回游标当前的位置
void insertFront(const T& item); //在表头插入节点
void insertRear(const T& item); //在表尾插入节点
void insertAt(const T& item); //在当前节点之前插入节点
void insertAfter(const T& item); //在当前节点之后插入节点
T deleteFront(); //删除头节点
void deleteCurrent(); //删除当前节点
T& data(); //返回对当前节点成员数据的引用
const T& data() const; //返回对当前节点成员数据的常引用
void clear(); //清空链表:释放所有节点的内存空间,被析构函数和operator=使用
};
//生成新节点,数据与为item,指针域为prtNext
template <class T>
Node<T>* LinkedList<T>::newNode(const T& item, Node<T> *ptrNext) {
Node<T> *n = new Node<T>(item, ptrNext);
return n;
}
//释放节点
template <class T>
void LinkedList<T>::freeNode(Node<T> *p) {
Node<T>* temp = front;
while (temp->next != p) {
temp = temp->next;
if (temp == currPtr)
position ++;
}
temp->next = p->next;
if (currPtr == p)
currPtr = currPtr->next;
if (prevPtr == p) {
prevPtr = prevPtr->next;
currPtr = currPtr->next;
}
delete p;
size --;
position --;
}
//将链表L复制到当前表(假设当前表为空),被复制构造函数和operator=调用
template <class T>
void LinkedList<T>::copy(const LinkedList<T>& L) {
Node<T> *temp = L.front, *ptr = front;
while (temp != L.rear) {
ptr->next = new Node<T>(temp->getData, NULL);
ptr = ptr->next;
temp = temp->next;
}
ptr->next = rear;
size = L.getSize();
position = L.currentPosition();
}
//构造函数
template <class T>
LinkedList<T>::LinkedList() {
front = new Node<T>();
rear = new Node<T>();
front->next = rear;
currPtr = rear;
prevPtr = front;
size = 0; //不计算front和rear
position = 0; //在front下一个元素视为0
}
//复制构造函数
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& L) {
clear();
copy(L);
}
//析构函数
template <class T>
LinkedList<T>::~LinkedList() {
LinkedList::clear();
delete front;
delete rear;
}
//重载赋值运算符
template <class T>
LinkedList<T>& LinkedList<T>::operator = (const LinkedList<T>& L) {
clear();
copy(L);
}
//返回链表中元素个数
template <class T>
int LinkedList<T>::getSize() const {
return size;
}
//链表是否为空
template <class T>
bool LinkedList<T>::isEmpty() const {
return (size == 0);
}
//初始化游标的位置
template <class T>
void LinkedList<T>::reset(int pos) { //初始化游标位置
if (pos > size) {
// cout << "越界,无法访问" << endl;
return;
}
int i = 0;
prevPtr = front;
currPtr = front->next;
while (i < pos) {
if (currPtr == rear) {
// cout << "越界,无法访问" << endl;
return;
}
i ++;
currPtr = currPtr->next;
prevPtr = prevPtr->next;
}
position = pos;
}
//使游标移动到下一个节点
template <class T>
void LinkedList<T>::next() {
if (currPtr == rear) {
// cout << "已经到达链表尾,无法移动" << endl;
return;
}
currPtr = currPtr->next;
prevPtr = prevPtr->next;
position ++;
}
//游标是否移动到链尾
template <class T>
bool LinkedList<T>::endOfList() const {
return (currPtr == rear);
}
//返回游标当前的位置
template <class T>
int LinkedList<T>::currentPosition() const {
return position;
}
//在表头插入节点
template <class T>
void LinkedList<T>::insertFront(const T& item) {
Node<T>* n = new Node<T>(item, front);
front = n;
size ++;
position ++;
}
//在表尾插入节点
template <class T>
void LinkedList<T>::insertRear(const T& item) {
Node<T>* temp = front;
while (temp->next != rear)
temp = temp->next;
Node<T> *n = new Node<T>(item, rear);
temp->next = n;
size ++;
}
//在当前节点之前插入节点
template <class T>
void LinkedList<T>::insertAt(const T& item) {
Node<T>* temp = new Node<T>(item, currPtr);
prevPtr->next = temp;
prevPtr = temp;
size ++;
position ++;
}
//在当前节点之后插入节点
template <class T>
void LinkedList<T>::insertAfter(const T& item) {
Node<T>* temp = new Node<T>(item, NULL);
temp->next = currPtr->next;
currPtr->next = temp;
size ++;
}
//删除头节点,实质是删除front->next
template <class T>
T LinkedList<T>::deleteFront() {
if (front->next == rear) {
// cout << "没有节点可以删除" << endl;
}
if (prevPtr == front->next) {
prevPtr = prevPtr->next;
currPtr = currPtr->next;
}
Node<T>* temp = front->next;
T d = temp->getData();
front->next = temp->next;
delete temp;
size --;
if (front->next != rear)
position --;
return d;
}
//删除当前节点
template <class T>
void LinkedList<T>::deleteCurrent() {
Node<T>* temp = currPtr;
currPtr = currPtr->next;
delete temp;
size --;
}
//返回对当前节点成员数据的引用
template <class T>
T& LinkedList<T>::data() {
return currPtr->getData();
}
//返回对当前节点成员数据的常引用
template <class T>
const T& LinkedList<T>::data() const {
return currPtr->getData();
}
//清空链表:释放所有节点的内存空间,被析构函数和operator=使用
template <class T>
void LinkedList<T>::clear() {
Node<T>* temp;
while (front->next != rear) {
temp = front->next;
front->next = temp->next;
delete temp;
}
size = 0;
position = 0;
}
/********** Begin **********/
template <class T>
class Queue : public LinkedList<T>{
};
/********** End **********/
using namespace std;
int main()
{
LinkedList<int> A, B;
int i, item;
// cout << "请输入加入链表A的五个整数:";
for (i = 0; i < 5; i ++) {
cin >> item;
A.insertRear(item);
}
// cout << "请输入加入链表B的五个整数:";
for (i = 0; i < 5; i ++) {
cin >> item;
B.insertRear(item);
}
// cout << endl << "有序链表A中的元素为:";
A.reset();
while(!A.endOfList()) {
cout << A.data() << " ";
A.next();
}
cout << endl;
// cout << endl << "有序链表B中的元素为:";
B.reset();
while(!B.endOfList()) {
A.insertRear(B.data());
cout << B.data() << " ";
B.next();
}
cout << endl;
// cout << endl << "加入链表B中元素后,链表A中的元素为:";
A.reset();
while(!A.endOfList()) {
cout << A.data() << " ";
A.next();
}
cout << endl;
return 0;
}
第3关:实现队列
#include <iostream>
template <class T>
class Node {
private:
T data;
public:
Node* next;
Node();
Node(const T& data, Node<T>* nt = 0);
// Node(T data, Node<T>* n = NULL);
T& getData();
};
template <class T>
Node<T>::Node() {
data = 0;
next = NULL;
}
template <class T>
Node<T>::Node(const T& d, Node<T>* nt) {
data = d;
next = nt;
}
template <class T>
T& Node<T>::getData() {
return data;
}
/*
* 在LinkedList的设计中,采用了附加指针front和rear,即链表的结构为front->a1->a2->...->rear
* 只有在析构函数中才删除这两个指针,其余的时间这两个指针都是存在的,其中的数据始终为0,不存储用户数据
*/
template <class T>
class LinkedList {
private:
Node<T> *front, *rear; //表头和表尾指针
Node<T> *prevPtr, *currPtr; //记录表当前遍历位置的指针,由插入和删除操作更新
int size; //表中元素个数
int position; //当前元素在表中的位置序号。由函数reset使用
Node<T>* newNode(const T& item, Node<T> *ptrNext = NULL); //生成新节点,数据与为item,指针域为prtNext
void freeNode(Node<T> *p); //释放节点
void copy(const LinkedList<T>& L); //将链表L复制到当前表(假设当前表为空),被复制构造函数和operator=调用
public:
LinkedList(); //构造函数
LinkedList(const LinkedList<T>& L); //复制构造函数
~LinkedList(); //析构函数
LinkedList<T>& operator = (const LinkedList<T>& L); //重载赋值运算符
int getSize() const; //返回链表中元素个数
bool isEmpty() const; //链表是否为空
void reset(int pos = 0); //初始化游标的位置
void next(); //使游标移动到下一个节点
bool endOfList() const; //游标是否移动到链尾
int currentPosition() const; //返回游标当前的位置
void insertFront(const T& item); //在表头插入节点
void insertRear(const T& item); //在表尾插入节点
void insertAt(const T& item); //在当前节点之前插入节点
void insertAfter(const T& item); //在当前节点之后插入节点
T deleteFront(); //删除头节点
void deleteCurrent(); //删除当前节点
T& data(); //返回对当前节点成员数据的引用
const T& data() const; //返回对当前节点成员数据的常引用
void clear(); //清空链表:释放所有节点的内存空间,被析构函数和operator=使用
};
//生成新节点,数据与为item,指针域为prtNext
template <class T>
Node<T>* LinkedList<T>::newNode(const T& item, Node<T> *ptrNext) {
Node<T> *n = new Node<T>(item, ptrNext);
return n;
}
//释放节点
template <class T>
void LinkedList<T>::freeNode(Node<T> *p) {
Node<T>* temp = front;
while (temp->next != p) {
temp = temp->next;
if (temp == currPtr)
position ++;
}
temp->next = p->next;
if (currPtr == p)
currPtr = currPtr->next;
if (prevPtr == p) {
prevPtr = prevPtr->next;
currPtr = currPtr->next;
}
delete p;
size --;
position --;
}
//将链表L复制到当前表(假设当前表为空),被复制构造函数和operator=调用
template <class T>
void LinkedList<T>::copy(const LinkedList<T>& L) {
Node<T> *temp = L.front, *ptr = front;
while (temp != L.rear) {
ptr->next = new Node<T>(temp->getData, NULL);
ptr = ptr->next;
temp = temp->next;
}
ptr->next = rear;
size = L.getSize();
position = L.currentPosition();
}
//构造函数
template <class T>
LinkedList<T>::LinkedList() {
front = new Node<T>();
rear = new Node<T>();
front->next = rear;
currPtr = rear;
prevPtr = front;
size = 0; //不计算front和rear
position = 0; //在front下一个元素视为0
}
//复制构造函数
template <class T>
LinkedList<T>::LinkedList(const LinkedList<T>& L) {
clear();
copy(L);
}
//析构函数
template <class T>
LinkedList<T>::~LinkedList() {
LinkedList::clear();
delete front;
delete rear;
}
//重载赋值运算符
template <class T>
LinkedList<T>& LinkedList<T>::operator = (const LinkedList<T>& L) {
clear();
copy(L);
}
//返回链表中元素个数
template <class T>
int LinkedList<T>::getSize() const {
return size;
}
//链表是否为空
template <class T>
bool LinkedList<T>::isEmpty() const {
return (size == 0);
}
//初始化游标的位置
template <class T>
void LinkedList<T>::reset(int pos) { //初始化游标位置
if (pos > size) {
// cout << "越界,无法访问" << endl;
return;
}
int i = 0;
prevPtr = front;
currPtr = front->next;
while (i < pos) {
if (currPtr == rear) {
// cout << "越界,无法访问" << endl;
return;
}
i ++;
currPtr = currPtr->next;
prevPtr = prevPtr->next;
}
position = pos;
}
//使游标移动到下一个节点
template <class T>
void LinkedList<T>::next() {
if (currPtr == rear) {
// cout << "已经到达链表尾,无法移动" << endl;
return;
}
currPtr = currPtr->next;
prevPtr = prevPtr->next;
position ++;
}
//游标是否移动到链尾
template <class T>
bool LinkedList<T>::endOfList() const {
return (currPtr == rear);
}
//返回游标当前的位置
template <class T>
int LinkedList<T>::currentPosition() const {
return position;
}
//在表头插入节点
template <class T>
void LinkedList<T>::insertFront(const T& item) {
Node<T>* n = new Node<T>(item, front);
front = n;
size ++;
position ++;
}
//在表尾插入节点
template <class T>
void LinkedList<T>::insertRear(const T& item) {
Node<T>* temp = front;
while (temp->next != rear)
temp = temp->next;
Node<T> *n = new Node<T>(item, rear);
temp->next = n;
size ++;
}
//在当前节点之前插入节点
template <class T>
void LinkedList<T>::insertAt(const T& item) {
Node<T>* temp = new Node<T>(item, currPtr);
prevPtr->next = temp;
prevPtr = temp;
size ++;
position ++;
}
//在当前节点之后插入节点
template <class T>
void LinkedList<T>::insertAfter(const T& item) {
Node<T>* temp = new Node<T>(item, NULL);
temp->next = currPtr->next;
currPtr->next = temp;
size ++;
}
//删除头节点,实质是删除front->next
template <class T>
T LinkedList<T>::deleteFront() {
if (front->next == rear) {
// cout << "没有节点可以删除" << endl;
}
if (prevPtr == front->next) {
prevPtr = prevPtr->next;
currPtr = currPtr->next;
}
Node<T>* temp = front->next;
T d = temp->getData();
front->next = temp->next;
delete temp;
size --;
if (front->next != rear)
position --;
return d;
}
//删除当前节点
template <class T>
void LinkedList<T>::deleteCurrent() {
Node<T>* temp = currPtr;
currPtr = currPtr->next;
delete temp;
size --;
}
//返回对当前节点成员数据的引用
template <class T>
T& LinkedList<T>::data() {
return currPtr->getData();
}
//返回对当前节点成员数据的常引用
template <class T>
const T& LinkedList<T>::data() const {
return currPtr->getData();
}
//清空链表:释放所有节点的内存空间,被析构函数和operator=使用
template <class T>
void LinkedList<T>::clear() {
Node<T>* temp;
while (front->next != rear) {
temp = front->next;
front->next = temp->next;
delete temp;
}
size = 0;
position = 0;
}
/********** Begin **********/
template <class T>
class Queue : public LinkedList<T>
{
public:
// Queue() {LinkedList();}
Queue() {}
void push(const T& item) {LinkedList<T>::insertRear(item);}
T pop() {return LinkedList<T>::deleteFront();}
};
/********** End **********/
#include <iostream>
using namespace std;
int main()
{
int item;
Queue<int> q;
// cout << "输入5个要插入的元素" << endl;
for (int i = 0; i < 5; i ++) {
cin >> item;
q.push(item);
}
for (int i = 0; i < 5; i ++)
// cout << "取出元素" << q.pop() << endl;
cout << q.pop() << " ";
cout<< endl;
return 0;
}
第4关:实现含排序功能的数组类
#include <iostream>
using namespace std;
template <class T>
class Array
{
T* alist;
int size;
public:
Array() {size = 0;}
Array(int sz) {alist = new T[sz]; size = sz;}
Array(T a[], int sz) {
size = sz;
alist = new T[size];
for (int i = 0; i < size; i ++)
alist[i] = a[i];
}
~Array() {size = 0; delete []alist;}
int getSize() {return size;}
T& operator [](int i) {return alist[i];}
void output(){
for(int i = 0; i < size; i ++)
cout << alist[i] << " ";
cout << endl;
}
void insertSort();
void selectSort();
void bubbleSort();
int seqSearch(T key);
};
/********** Begin **********/
// 在数组中顺序查找key元素,若找到则返回其索引值(是数组中第几个,从0算起),找不到则返回-1
template <class T>
int Array<T>::seqSearch(T key) {
int i;
for (i = 0; i < size; i ++)
if (alist[i] == key)
return i;
if (i == size) {
// cout << "没有找到元素" << endl;
return -1;
}
return -1;
}
// 插入排序
template <class T>
void Array<T>::insertSort(){
int i, j;
T temp;
//将下标为1~size-1的元素逐个插入到已排序序列中适当的位置
for (i = 1; i < size; i ++)
{
//从a[i-1]开始向a[0]方向扫描各元素,寻找适当位置插入a[i]
j = i;
temp = alist[i];
while (j > 0 && temp < alist[j-1])
{ //逐个比较,直到temp>=a[j-1]时,j便是应插入的位置。
alist[j] = alist[j-1]; //将元素逐个后移,以便找到插入位置时可立即插入。
j--;
}
//插入位置已找到,立即插入。
alist[j] = temp;
}
}
// 选择排序
template <class T>
void Array<T>::selectSort(){
int minIndex; //每一次选出的最小元素之下标
int i, j;
T temp;
//sort a[0]..a[size-2], and a[size-1] is in place
for (i = 0; i < size - 1; i ++)
{
minIndex = i; //最小元素之下标初值设为i
//在元素a[i+1]..a[size-1]中逐个比较显出最小值
for (j = i + 1; j < size; j++)
//minIndex始终记录当前找到的最小值的下标
if (alist[j] < alist[minIndex])
minIndex = j;
//将这一趟找到的最小元素与a[i]交换
temp = alist[i];
alist[i] = alist[minIndex];
alist[minIndex] = temp;
}
}
template <class T>
void Array<T>::bubbleSort(){
T temp;
int i, j;
for (i = 1; i < size; i ++) {
for (j = size - 1; j >= i; j --) {
if (alist[j - 1] > alist[j]) {
temp = alist[j];
alist[j] = alist[j - 1];
alist[j - 1] = temp;
}
}
}
}
/********** End **********/
int main()
{
int a[5] = {3, 6, 1, 8, 2};
Array<int> iArray(a, 5);
iArray.insertSort();
iArray.output();
double d[4] = {4.1, 3.2, 5.6, 1.9};
Array<double> dArray(d, 4);
dArray.selectSort();
dArray.output();
char c[3] = {'g', 'c', 'A'};
Array<char> cArray(c, 3);
cArray.bubbleSort();
cArray.output();
int b[4] = {-1, 2, 0, 5};
Array<int> bArray(b, 4);
cout<< bArray.seqSearch(0)<< endl;
cout<< bArray.seqSearch(3)<< endl;
return 0;
}