问题描述
设计一个有序线性表类,要求完成初始化,插入和遍历功能,使得表内元素实现有序排列(从小到大)。同时实现合并功能,使得两个线性表能够合并为一个线性表(可能存在重复元素)。
- 要求使用链表和泛型编程。
- 注:不要忘了回收指针。
输入
第一行输入字符串 dtype(“int”或者”float”)表示数据存储类型。
第二行输入 int 型数据 N1(N1≥0),代表第一个线性表元素数量;
第三行输入 N1 个 dtype 型数据,每个数据由空格隔开;
第四行输入 int 型数据 N2(N2≥0),代表第二个线性表元素数量;
第五行输入 N2 个 dtype 型数据,每个数据由空格隔开;
输出
遍历第一个线性表,第一行输出其遍历结果,每个数据由空格隔开。
遍历第二个线性表,第二行输出其遍历结果,每个数据由空格隔开。
第三行输出第一个线性表和第二个线性表合并后的遍历结果,每个数据由空格隔开。
- 注:线性表为空时仅输出换行符,每行输出的末尾没有空格。
样例
输入:
int
7 15 24 0 13 7 15 8
3 15 1 2输出:
0 7 8 13 15 15 24
1 2 15
0 1 2 7 8 13 15 15 15 24
解题步骤
结点类
该题需采用泛型编程,故定义结点类时需要使用模板
template <typename T>
struct Node
{
Node* next;
T value;
};
链表类
链表只需要头指针用来指向链表的起点,构造函数只需让head指向空结点,析构函数则用来删除链表中所有的结点
class List
{
public:
Node<T>* head;
List() : head(nullptr) {
head = new Node<T>;
head->next = nullptr;
};
~List()
{
Node<T>* p;
while (head != nullptr)
{
p = head;
head = head->next;
delete p;
}
}
};
insert函数
向队列中插入一个节点,值为value,使得表内元素实现有序排列(从小到大)
在链表中插入结点时,若链表为空,则将该新结点作为空结点,若链表不为空,题目要求该链表为有序线性表,故需要先通过比较新插入的结点值与链表结点值,找到结点插入的位置再进行插入
void insert(T value)
{
Node<T>* p = head; //获得头节点指针
Node<T>* node = new Node<T>; //创建新的节点
node->value = value;
node->next = nullptr;
Node<T>* tem = head;
if (p == nullptr) p->value = value;
for (; p != nullptr;)
{
if (node->value > p->value)
{
tem = p;
p = p->next;
}
else
{
node->next = tem->next;
tem->next = node;
break;
}
}
if (tem && tem->next != node)
{
tem->next = node;
}
}
printAll函数
遍历并输出线性表
从头指针开始遍历即可,不断输出结点值大小
void printAll()
/*
函数名:printAll
输入值:无
功 能:遍历并输出线性表
*/
{
Node<T>* p = head->next;
if (p == nullptr)
{
cout << endl;
return;
}
for (; p->next != nullptr;)
{
cout << p->value << " ";
p = p->next;
}
cout << p->value;
cout << endl;
}
merge函数
合并两个线性表
遍历线性表2,使用insert函数将表2的结点插入表1,即可实现表1和表2的合并
void merge(List<T>* l2)
{
Node<T>* p = l2->head->next;
for (; p != nullptr;)
{
insert(p->value);
p = p->next;
}
}
test函数
调用链表函数完成题目要求
void test()
{
int N1, N2;
T value;
List<T> l1, l2;
cin >> N1;
for (; N1 > 0; N1--)
{
cin >> value;
l1.insert(value);
}
l1.printAll();
cin >> N2;
for (; N2 > 0; N2--)
{
cin >> value;
l2.insert(value);
}
l2.printAll();
l1.merge(&l2);
l1.printAll();
}
完整代码
#include <iostream>
using namespace std;
template <typename T>
struct Node
{
Node* next;
T value;
};
template <typename T>
class List
{
public:
Node<T>* head;
List() : head(nullptr) {
head = new Node<T>;
head->next = nullptr;
};
~List()
{
Node<T>* p;
while (head != nullptr)
{
p = head;
head = head->next;
delete p;
}
}
void insert(T value)
{
Node<T>* p = head; //获得头节点指针
Node<T>* node = new Node<T>; //创建新的节点
node->value = value;
node->next = nullptr;
Node<T>* tem = head;
if (p == nullptr) p->value = value;
for (; p != nullptr;)
{
if (node->value > p->value)
{
tem = p;
p = p->next;
}
else
{
node->next = tem->next;
tem->next = node;
break;
}
}
if (tem && tem->next != node)
{
tem->next = node;
}
}
void printAll()
{
Node<T>* p = head->next;
if (p == nullptr)
{
cout << endl;
return;
}
for (; p->next != nullptr;)
{
cout << p->value << " ";
p = p->next;
}
cout << p->value;
cout << endl;
}
void merge(List<T>* l2)
{
Node<T>* p = l2->head->next;
for (; p != nullptr;)
{
insert(p->value);
p = p->next;
}
}
};
template <typename T>
void test()
{
int N1, N2;
T value;
List<T> l1, l2;
cin >> N1;
for (; N1 > 0; N1--)
{
cin >> value;
l1.insert(value);
}
l1.printAll();
cin >> N2;
for (; N2 > 0; N2--)
{
cin >> value;
l2.insert(value);
}
l2.printAll();
l1.merge(&l2);
l1.printAll();
}
int main()
{
string dtype;
cin >> dtype;
if (dtype == "int")
test<int>();
else
test<float>();
return 0;
}