习题1
1.1 题目:
编写一个函数模板,分别求一个组数里面数据的最大值,最小值和平均值。
1.2 解题思路:
- 定义模板类型T
- 编写函数MathHelper求数组数据的最大值、最小值和平均值
- 用double和int两组数据进行测试
1.3 代码及注释:
#include<iostream>
using namespace std;
//求一个数列的最大值、最小值、均值
template<typename T>
void MathHelper(T num[], int size) {
T max = num[0], min = num[0], total = 0;
for (int i = 0;i < size;i++) {
if (num[i] > max)
max = num[i];
if (num[i] < min)
min = num[i];
total += num[i];
}
//显示最大值、最小值、均值
cout << "Max : " << max << endl;
cout << "Min : " << min << endl;
if (size == 0)
cout << "Mean : " << 0 << endl;
else
cout << "Mean : " << total / double(size) << endl;
}
void main() {
//测试
int a[10] = { 2,1,9,10,7,6,5,8,3,4 };
double b[10] = { 2.5,1.5,9.5,10.5,7.5,6.5,5.5,8.5,3.5,4.5 };
MathHelper<int>(a, sizeof(a) / sizeof(a[0]));
cout << endl;
MathHelper<double>(b, sizeof(b) / sizeof(b[0]));
}
1.4 程序运行结果分析:
构造两个不同类型的数组数据进行测试,结果如下:
Max : 10
Min : 1
Mean : 5.5
Max : 10.5
Min : 1.5
Mean : 6
请按任意键继续. . .
验证可得程序执行正确。
习题2
2.1 题目:
编写一个函数模板,实现数据交换的操作。
2.2 解题思路:
- 定义模板类型T
- 编写函数Swap对两个相同类型的数据进行互换
- 用double、int和char三种不同类型的数据进行实验
2.3 代码及注释:
#include<iostream>
using namespace std;
// 定义交换函数Swap
template<typename T>
void Swap(T& a, T& b) {
T c = a;
a = b;
b = c;
}
int main() {
// 测试数据
int a1 = 10, b1 = -8;
cout << "Before swapping:" << endl;
cout << "a1 = " << a1 << endl;
cout << "b1 = " << b1 << endl;
Swap<int>(a1, b1);
cout << "After swapping:" << endl;
cout << "a1 = " << a1 << endl;
cout << "b1 = " << b1 << endl << endl;
double a2 = 10.35, b2 = -11.23;
cout << "Before swapping:" << endl;
cout << "a2 = " << a2 << endl;
cout << "b2 = " << b2 << endl;
Swap<double>(a2, b2);
cout << "After swapping:" << endl;
cout << "a2 = " << a2 << endl;
cout << "b2 = " << b2 << endl << endl;
char a3 = 'K', b3 = 'E';
cout << "Before swapping:" << endl;
cout << "a3 = " << a3 << endl;
cout << "b3 = " << b3 << endl;
Swap<char>(a3, b3);
cout << "After swapping:" << endl;
cout << "a3 = " << a3 << endl;
cout << "b3 = " << b3 << endl << endl;
}
2.4 程序运行结果分析:
构造的三组不同类型的数据,测试结果如下:
Before swapping:
a1 = 10
b1 = -8
After swapping:
a1 = -8
b1 = 10
Before swapping:
a2 = 10.35
b2 = -11.23
After swapping:
a2 = -11.23
b2 = 10.35
Before swapping:
a3 = K
b3 = E
After swapping:
a3 = E
b3 = K
请按任意键继续. . .
因此,程序执行正确。
习题3
3.1 题目:
编写如下形式的排序函数模板:
template<class Type>void sort(Type* A, int n, bool f)
对一个具有n个Type类型的一维数组进行排序,f为1表示从小到大排序,f为0表示从大到小排序,并通过不同参数类型机型调用,验证正确性。
注意:
- int double char型至少三种类型进行测试,int和double类型数组内容建议使用random()生成
- 排序前的状态和排序后的状态都应该进行输出
- 注意是在原始的数组上进行排序,不能新开辟数组
3.2 解题思路:
- 定义模板类型T
- 编写Sort函数对数组数据进行排序
- 排序算法中,快排、堆排、归并排序等算法平均时间复杂度都是o(nlogn)级别的,这里我们采用快排对数据进行排序。
- 编写Display函数对数据进行展示
- 利用随机种子和伪随机数对int、double、char三个类型的数据进行赋值
- 验证结果的合理性
3.3 代码及注释:
#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;
// 编写Sort函数,传参进快速排序
template<typename T>
void Sort(T* A, int n, bool f) {
QuickSort(A, 0, n - 1, f);
}
// 快速排序算法
template<typename T>
void QuickSort(T arr[], int left, int right, bool f) {
if (left >= right)return;
T key = arr[left];
int i = left + 1;
int j = right;
while (true) {
if (f) {
while (arr[i] < key) {
if (i == right)break;
i++;
}
while (arr[j] > key) {
if (j == left)break;
j--;
}
}
else {
while (arr[i] > key) {
if (i == right)break;
i++;
}
while (arr[j] < key) {
if (j == left)break;
j--;
}
}
if (j <= i)break;
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
T temp = arr[j];
arr[j] = arr[left];
arr[left] = temp;
QuickSort(arr, left, j - 1, f);
QuickSort(arr, j + 1, right, f);
}
// 显示数组内数据
template<typename T>
void Display(T* A, int n) {
for (int i = 0; i < n; i++)
cout << A[i] << " ";
cout << endl;
}
void main() {
srand(time(0));
// 对int类型数组进行测试
int a[10];
for (int i = 0; i < 10; i++)
a[i] = rand() % 100 * pow(-1, rand());
cout << "Befor sorting :" << endl;
Display<int>(a, 10);
cout << "After sorting :" << endl;
Sort<int>(a, 10, 0);
Display<int>(a, 10);
Sort<int>(a, 10, 1);
Display<int>(a, 10);
cout << endl << endl;
// 对double类型数组进行测试
double b[10];
for (int i = 0; i < 10; i++)
b[i] = (rand() % 100) * pow(-1, rand()) / 7;
cout << "Befor sorting :" << endl;
Display<double>(b, 10);
cout << "After sorting :" << endl;
Sort<double>(b, 10, 0);
Display<double>(b, 10);
Sort<double>(b, 10, 1);
Display<double>(b, 10);
cout << endl << endl;
// 对char类型数组进行测试
char c[10];
for (int i = 0; i < 10; i++)
c[i] = (rand() % 74) + 48;
cout << "Befor sorting :" << endl;
Display<char>(c, 10);
cout << "After sorting :" << endl;
Sort<char>(c, 10, 0);
Display<char>(c, 10);
Sort<char>(c, 10, 1);
Display<char>(c, 10);
cout << endl << endl;
}
3.4 程序运行结果分析:
我们设置不同的值对其进行调试,其中包括三个不同的类型,测试结果如下:
Befor sorting :
53 85 63 -91 53 79 20 -86 49 3
After sorting :
85 79 63 53 53 49 20 3 -86 -91
-91 -86 3 20 49 53 53 63 79 85
Befor sorting :
-11.8571 -1.71429 14 -10.2857 -4.28571 -1.85714 4.28571 -7.57143 9.28571 -4.14286
After sorting :
14 9.28571 4.28571 -1.71429 -1.85714 -4.14286 -4.28571 -7.57143 -10.2857 -11.8571
-11.8571 -10.2857 -7.57143 -4.28571 -4.14286 -1.85714 -1.71429 4.28571 9.28571 14
Befor sorting :
i n E ] r D g j O 6
After sorting :
r n j i g ] O E D 6
6 D E O ] g i j n r
请按任意键继续. . .
验证三组测试实验表明,程序执行正确。
习题4
4.1 题目:
编写一个类模板,完成对不同数据类型的数组的排序(小到大)操作。
如:
- int array[5]={3,6,2,1,4};
- double array[5]={3.1,1.2,4.5,1.1,0.2};
4.2 解题思路:
- 创建Sort类
- 定义QuickSort方法,利用快速排序对数据进行排序
- 重载cout函数输出结果
4.3 代码及注释:
#include<iostream>
using namespace std;
// 定义Sort类
template<class T>
class Sort {
public:
Sort(T A[], int len_) { arr = A; len = len_; }
void QuickSort() { QuickSort(0, len - 1); }
void Display(ostream& out)const {
for (int i = 0; i < len; i++) out << arr[i] << " ";
}
private:
void QuickSort(int left, int right);
T* arr;
int len;
};
// 利用快速排序算法对数据进行排序
template<class T>
void Sort<T>::QuickSort(int left, int right) {
if (left >= right)
return;
T key = arr[left];
int i = left + 1;
int j = right;
while (true) {
while (arr[i] < key) {
if (i == right)break;
i++;
}
while (arr[j] > key) {
if (j == left)break;
j--;
}
if (i >= j)break;
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
T temp = arr[j];
arr[j] = arr[left];
arr[left] = temp;
QuickSort(left, j - 1);
QuickSort(j + 1, right);
}
// 重载cout函数
template<class T>
ostream& operator<<(ostream& out, const Sort<T>& A) {
A.Display(out);
return out;
}
int main() {
// 测试题目给定数据
int a[5] = { 3,6,2,1,4 };
Sort<int> sort_a(a, 5);
cout << "排序前:" << sort_a << endl;
sort_a.QuickSort();
cout << "排序后:" << sort_a << endl << endl;
double b[5] = { 3.1,1.2,4.5,1.1,0.2 };
Sort<double> sort_b(b, 5);
cout << "排序前:" << sort_b << endl;
sort_b.QuickSort();
cout << "排序后:" << sort_b << endl << endl;
return 0;
}
4.4 程序运行结果分析:
根据题目数据进行测试,结果如下:
排序前:3 6 2 1 4
排序后:1 2 3 4 6
排序前:3.1 1.2 4.5 1.1 0.2
排序后:0.2 1.1 1.2 3.1 4.5
请按任意键继续. . .
因此,程序执行正确。
习题5
5.1 题目:
定义一个堆栈类模板,实现不同数据类型数据的入栈和出栈操作,堆栈的大小用非类型参数指定。
5.2 解题思路:
- 定义Stack类,堆栈的大小用非类型参数指定
- 编写Stack类的成员方法
- 重载cout函数
- 利用try-catch方法进行异常捕获和处理
- 进行调试测验
5.3 代码及注释:
#include<iostream>
using namespace std;
// 定义Stack类
template<class T, int MaxSize>
class Stack {
public:
Stack() {
elems = new T[MaxSize];
top = -1;
}
~Stack() { delete elems; }
bool IsEmpty()const { return top == -1; }
bool IsFull()const { return top == MaxSize; }
T Top()const;
Stack<T, MaxSize>& Push(const T& x);
Stack<T, MaxSize>& Pop(T& x);
void Display()const;
private:
int top;
T * elems;
};
// 返回Stack首元素
template<class T, int MaxSize>
T Stack<T, MaxSize>::Top()const {
if (IsEmpty())
throw out_of_range("Stack<>::Top(): empty stack");
return elems[top];
}
// 进行Push操作
template<class T, int MaxSize>
Stack<T, MaxSize>& Stack<T, MaxSize>::Push(const T& x) {
if (IsFull())
throw out_of_range("Stack<>::Push(): full stack");
elems[++top] = x;
return *this;
}
// 进行Pop操作
template<class T, int MaxSize>
Stack<T, MaxSize>& Stack<T, MaxSize>::Pop(T& x) {
if (IsEmpty())
throw out_of_range("Stack<>::Pop(): empty stack");
x = elems[top--];
return *this;
}
// 显示Stack内所有元素,从栈底到栈顶依次显示
template<class T, int MaxSize>
void Stack<T, MaxSize>::Display()const {
if (IsEmpty())
cout << "None" << endl;
else {
for (int i = 0;i <= top;i++)
cout << elems[i] << " ";
}
}
// 重载ostream成员函数cout
template<class T, int MaxSize>
ostream& operator<<(ostream& out,const Stack<T, MaxSize>& s) {
s.Display();
return out;
}
int main() {
// 构造不同数据类型进行测试验证
try {
Stack<int, 10> stack_int;
for (int i = 0;i < 10;i++)
stack_int.Push(5 * i);
cout << "stack_int: " << stack_int << endl;
cout << "delete two elements: ";
for (int i = 0;i < 2;i++) {
int x;
stack_int.Pop(x);
cout << x << " ";
}
cout << endl << "stack_int: " << stack_int << endl << endl << endl;
Stack<double, 10> stack_double;
for (int i = 0;i < 10;i++)
stack_double.Push(5.2 * i + 0.3);
cout << "stack_double: " << stack_double << endl;
cout << "delete two elements: ";
for (int i = 0;i < 2;i++) {
double x;
stack_double.Pop(x);
cout << x << " ";
}
cout << endl << "stack_double: " << stack_double << endl << endl << endl;
Stack<char, 10> stack_char;
for (int i = 0;i < 10;i++)
stack_char.Push(2 * i + 68);
cout << "stack_char: " << stack_char << endl;
cout << "delete two elements: ";
for (int i = 0;i < 2;i++) {
char x;
stack_char.Pop(x);
cout << x << " ";
}
cout << endl << "stack_char: " << stack_char << endl << endl << endl;
return 0;
}
catch (exception& ex) {
cout << ex.what() << endl;
return EXIT_FAILURE;
}
}
5.4 程序运行结果分析:
我们对Stack类构建了三种不同的数据类型进行测试,实验结果如下:
stack_int: 0 5 10 15 20 25 30 35 40 45
delete two elements: 45 40
stack_int: 0 5 10 15 20 25 30 35
stack_double: 0.3 5.5 10.7 15.9 21.1 26.3 31.5 36.7 41.9 47.1
delete two elements: 47.1 41.9
stack_double: 0.3 5.5 10.7 15.9 21.1 26.3 31.5 36.7
stack_char: D F H J L N P R T V
delete two elements: V T
stack_char: D F H J L N P R
请按任意键继续. . .
由实验结果可知:程序执行正确。
习题6
6.1 题目:
用类模板创建单链表,并实现在链表里增加一个节点和删除一个节点的操作。
6.2 解题思路:
- 定义链表结点类Node
- 定义链表类List
- 编写List成员方法
- 重载cout函数输出
- 利用try-catch方法进行异常调试
- 构造三种不同类型的数据进行测试
6.3 代码及注释:
#include<iostream>
using namespace std;
// 定义链表结点类Node
template<class T>
class Node {
public:
T data;
Node<T>* next;
};
// 定义链表类List
template<class T>
class List {
public:
List() { first = 0; }
bool IsEmpty() { return first == 0; }
int Length()const;
List<T>& Insert(int num, const T& x);
List<T>& Delete(int num, T& x);
void Display(ostream& out) const;
private:
Node<T>* first;
};
// 返回链表长度
template<class T>
int List<T>::Length()const {
int num = 0;
for (Node<T>* current = first; current; current = current->next)
num++;
return num;
}
// 插入元素
template<class T>
List<T>& List<T>::Insert(int num, const T& x) {
if (num < 0)
throw out_of_range("List<>::Insert():error num");
Node<T>* current = first;
for (int i = 1; i < num && current; i++)
current = current->next;
if (!current && num > 0)
throw out_of_range("List<>::Insert():error num");
Node<T>* p = new Node<T>;
p->data = x;
if (num) {
p->next = current->next;
current->next = p;
}
else {
p->next = first;
first = p;
}
return *this;
}
// 删除元素
template<class T>
List<T>& List<T>::Delete(int num, T& x) {
if (num < 1 || first == 0)
throw out_of_range("List<>::Delete():error num");
Node<T>* current = first;
if (num == 1)
first = first->next;
else {
Node<T>* p = first;
for (int i = 1; i < num - 1 && p; i++)
p = p->next;
if (!p || !p->next)
throw out_of_range("List<>::Delete():error num");
current = p->next;
p->next = current->next;
}
x = current->data;
delete current;
return *this;
}
// 展示元素
template<class T>
void List<T>::Display(ostream& out)const {
for (Node<T>* current = first; current; current = current->next)
out << current->data << " ";
}
// 重载cout函数
template<class T>
ostream& operator<<(ostream& out, const List<T>& A) {
A.Display(out);
return out;
}
int main() {
try {
// 创建三种不同类型的数据进行调试测验
List<char> list_char;
list_char.Insert(0, 'a');
list_char.Insert(0, 'b');
list_char.Insert(0, 'c');
list_char.Insert(0, 'd');
cout << "原来的List :" << list_char << endl;
list_char.Insert(0, 'e');
cout << "添加首元素后的List:" << list_char << endl;
char x;
list_char.Delete(5, x);
cout << "删除尾元素后的List:" << list_char << endl << endl;
List<double> list_double;
list_double.Insert(0, 1.32);
list_double.Insert(0, 2.34);
list_double.Insert(0, 11.2);
list_double.Insert(0, 5.6);
cout << "原来的List :" << list_double << endl;
list_double.Insert(0, 3.08);
cout << "添加首元素后的List:" << list_double << endl;
double y;
list_double.Delete(5, y);
cout << "删除尾元素后的List:" << list_double << endl << endl;
List<int> list_int;
list_int.Insert(0, 11);
list_int.Insert(0, 23);
list_int.Insert(0, 36);
list_int.Insert(0, 20);
cout << "原来的List :" << list_int << endl;
list_int.Insert(0, 37);
cout << "添加首元素后的List:" << list_int << endl;
int z;
list_int.Delete(5, z);
cout << "删除尾元素后的List:" << list_int << endl << endl;
return EXIT_SUCCESS;
}
catch (exception& ex) {
cout << ex.what() << endl;
return EXIT_FAILURE;
}
}
6.4 程序运行结果分析:
构建三种不同的数据类型进行测试,结果如下:
原来的List :d c b a
添加首元素后的List:e d c b a
删除尾元素后的List:e d c b
原来的List :5.6 11.2 2.34 1.32
添加首元素后的List:3.08 5.6 11.2 2.34 1.32
删除尾元素后的List:3.08 5.6 11.2 2.34
原来的List :20 36 23 11
添加首元素后的List:37 20 36 23 11
删除尾元素后的List:37 20 36 23
请按任意键继续. . .
由结果得,程序执行正确。