最近在学链表的时候,看课本上每次设置链表时都要设置数据类型。于是突发奇想,能不能创建一个能自动识别元素类型的链表。
能自动识别元素类型了,那为什么不对每一个元素都自定义类型,做一个可以包罗万象的链表
那链表都做出来了,拓展到数组岂不是更好
于是便有这个点子
#include <iostream>
#include <string>
using namespace std;
// 数据类型枚举
enum data_type {
int_type,
double_type,
string_type
};
// 结构体
struct elemtype {
int int_data;
double double_data;
string string_data;
// 默认构造函数
elemtype() : int_data(0), double_data(0.0), string_data("") {}
};
// 单链表结点
struct l_node {
elemtype datas; // 数据
int type; // 数据类型
l_node *next; // 指向下一个节点的指针
// 默认构造函数
l_node() : next(nullptr) {}
};
//双链表结点
struct d_node {
elemtype datas;
d_node *next, *prev;
int type;
//默认构造函数
d_node(): next(nullptr), prev(nullptr) {}
};
typedef d_node* d_linklist; // 双链表指针定义
typedef l_node* l_linklist; // 单链表指针定义
//函数声明
void input(elemtype *ep, int *ep_type);
void visit(elemtype *ep, int ep_type);
void create_l_link_f(l_linklist *l, int n, void(*input_func)(elemtype*, int*));
void create_d_link_f(d_linklist *d, int n, void(*input_func)(elemtype*, int*));
void create_l_link_r(l_linklist *l, int n, void(*input_func)(elemtype*, int*));
void create_d_link_r(d_linklist *d, int n, void(*input_func)(elemtype*, int*));
void l_list_traverse(l_linklist l, void(*visit_func)(elemtype*, int));
void d_list_traverse(d_linklist d, void(*visit_func)(elemtype*, int));
void create_l_links_array(l_linklist* l, void(*create_l_link_type)(l_linklist*, int list_num, void(*input_func)(elemtype*, int*)), int list_num, int num_of_lists);
void create_d_links_array(d_linklist* d, void(*create_d_link_type)(d_linklist*, int list_num, void(*input_func)(elemtype*, int*)), int list_num, int num_of_lists);
void l_list_array_traverse(l_linklist* listsAddressSave, int num_of_lists);
void d_list_array_traverse(d_linklist* listsAddressSave, int num_of_lists);
// 向链表中输入内容 存在浮点整型不分的问题
void input(elemtype *ep, int *ep_type) {
string input_str;
cin >> input_str;
try {
// 尝试将输入转换为浮点数
ep->double_data = stod(input_str);
*ep_type = double_type; // 标记数据类型为浮点数
cout << "为浮点数" << endl;
} catch (const invalid_argument&) {
try {
// 尝试将输入转换为整数
ep->int_data = stoi(input_str);
*ep_type = int_type; // 标记数据类型为整数
cout << "为整数" << endl;
} catch (const invalid_argument&) {
// 如果输入无法转换为整数或浮点数,则将其视为字符串
ep->string_data = input_str;
*ep_type = string_type; // 标记数据类型为字符串
cout << "为字符串" << endl;
}
}
}
// 根据数据类型打印数据的函数
void visit(elemtype *ep, int ep_type) {
switch (ep_type) {
case int_type:
cout << ep->int_data << " "; // 打印整数数据
break;
case double_type:
cout << ep->double_data << " "; // 打印浮点数数据
break;
case string_type:
cout << ep->string_data << " "; // 打印字符串数据
break;
}
}
// 使用头插法创建单链表
void create_l_link_f(l_linklist *l, int n, void(*input_func)(elemtype*, int*)) {
*l = nullptr;
for (int i = 0; i < n; ++i) {
l_linklist newNode = new l_node;
input_func(&(newNode->datas), &(newNode->type)); // 输入数据
newNode->next = *l;
*l = newNode;
}
}
//使用头插法创建双链表
void create_d_link_f(d_linklist *d, int n, void(*input_func)(elemtype*, int*)) {
*d = nullptr;
for (int i = 0; i < n; ++i) {
d_linklist newNode = new d_node;
input_func(&(newNode->datas), &(newNode->type));
newNode->next = *d;
newNode->prev = nullptr;
if (*d != nullptr) {
(*d)->prev = newNode;
}
*d = newNode; //更新头结点为新结点
}
}
//使用尾插法创建单链表
void create_l_link_r(l_linklist *l, int n, void(*input_func)(elemtype*, int*)) {
*l = nullptr;
l_linklist newNode, lastNode;
lastNode = *l = new l_node;
for (int i = 0; i < n; ++i) {
if (i == 0) {
newNode = lastNode;
} else {
newNode = new l_node;
}
input_func(&(newNode->datas), &(newNode->type));
lastNode->next = newNode, lastNode = newNode;
}
}
//使用头插法创建双链表
void create_d_link_r(d_linklist *d, int n, void(*input_func)(elemtype*, int*)) {
*d = nullptr;
d_linklist newNode, lastNode;
lastNode = *d = new d_node;
for (int i = 0; i < n; ++i) {
if (i == 0) {
newNode = lastNode;
newNode->prev = *d;
} else {
newNode = new d_node;
newNode->prev = lastNode;
}
input_func(&(newNode->datas), &(newNode->type));
lastNode->next = newNode, lastNode = newNode;
}
}
// 遍历单链表并对每个节点应用 visit 函数
void l_list_traverse(l_linklist l, void(*visit_func)(elemtype*, int)) {
l_linklist p = l;
while (p != nullptr) {
visit_func(&(p->datas), p->type); // 对每个节点应用 visit 函数
p = p->next;
}
}
// 遍历双链表并对每个节点应用 visit 函数
void d_list_traverse(d_linklist d, void(*visit_func)(elemtype*, int)) {
d_linklist p = d;
while (p != nullptr) {
visit_func(&(p->datas), p->type); // 对每个节点应用 visit 函数
p = p->next;
}
}
//创建一个单链表数组
void create_l_links_array(l_linklist* l, void(*create_l_link_type)(l_linklist*, int list_num, void(*input_func)(elemtype*, int*)), int list_num, int num_of_lists) {
l_linklist listsAddressSave[num_of_lists];
for (int i = 0; i < num_of_lists; ++i) {
l_linklist listPointer;
cout << "请输入元素:" << endl;
create_l_link_type(&listPointer, list_num, input);
listsAddressSave[i] = listPointer;
}
for (int i = 0; i < num_of_lists; ++i) {
l[i] = listsAddressSave[i];
}
}
//创建一个双链表数组
void create_d_links_array(d_linklist* d, void(*create_d_link_type)(d_linklist*, int list_num, void(*input_func)(elemtype*, int*)), int list_num, int num_of_lists) {
d_linklist listsAddressSave[num_of_lists];
for (int i = 0; i < num_of_lists; ++i) {
d_linklist listPointer;
cout << "请输入元素:" << endl;
create_d_link_type(&listPointer, list_num, input);
listsAddressSave[i] = listPointer;
}
for (int i = 0; i < num_of_lists; ++i) {
d[i] = listsAddressSave[i];
}
}
// 遍历单链表数组并对每个节点应用 visit 函数
void l_list_array_traverse(l_linklist* listsAddressSave, int num_of_lists) {
for (int i = 0; i < num_of_lists; i++) {
cout << "第 " << i + 1 << " 个链表的元素: ";
l_list_traverse(listsAddressSave[i], visit);
cout << endl;
}
}
// 遍历双链表数组并对每个节点应用 visit 函数
void d_list_array_traverse(d_linklist* listsAddressSave, int num_of_lists) {
for (int i = 0; i < num_of_lists; i++) {
cout << "第 " << i + 1 << " 个链表的元素: ";
d_list_traverse(listsAddressSave[i], visit);
cout << endl;
}
}
int main() {
l_linklist l; // 定义链表
d_linklist d;
int array;
cout << "请选择输入类型" << endl << "1,单个链表" << endl << "2,链表数组" << endl;
cin >> array;
if (array == 1) {
int n;
cout << "请输入元素个数:";
cin >> n; // 输入元素个数
int chooseType, listType;
cout << "请选择创建类型:" << endl << "1,倒序尾插法" << endl << "2,顺序头插法" << endl;
cin >> chooseType; // 输入创建类型
cout << "请选择链表类型:" << endl << "1,单链表" << endl << "2,双链表" << endl;
cin >> listType; // 输入链表类型
if (chooseType == 1 && listType == 1) {
cout << "请输入元素:" << endl;
create_l_link_f(&l, n, input); // 头插法创建单链表
} else if (chooseType == 2 && listType == 1) {
cout << "请输入元素:" << endl;
create_l_link_r(&l, n, input); // 尾插法创建单链表
} else if (chooseType == 1 && listType == 2) {
cout << "请输入元素:" << endl;
create_d_link_f(&d, n, input); // 头插法创建双链表
} else if (chooseType == 2 && listType == 2) {
cout << "请输入元素:" << endl;
create_d_link_r(&d, n, input); // 尾插法创建双链表
} else {
cout << "请检查你的输入";
return 0;
}
cout << "链表元素:";
if (listType == 1) {
l_list_traverse(l, visit); // 遍历单链表并打印元素
cout << endl;
} else if (listType == 2) {
d_list_traverse(d, visit); // 遍历双链表并打印元素
cout << endl;
}
} else if (array == 2) {
int list_num;
cout << "请输入元素个数:";
cin >> list_num; // 输入元素个数
int num_of_lists;
cout << "请输入链表个数: ";
cin >> num_of_lists;
l_linklist lArray[num_of_lists]; // 定义链表
d_linklist dArray[num_of_lists];
l_linklist* lp = lArray;
d_linklist* dp = dArray;
int arrayType;
cout << "请选择链表数组类型" << endl << "1,单链表数组" << endl << "2,双链表数组" << endl;
cin >> arrayType;
if (arrayType == 1) {
int arrayType;
cout << "请选择创建类型" << endl << "1,逆序头插法" << endl << "2,顺序尾插法" << endl;
cin >> arrayType;
if (arrayType == 1) {
create_l_links_array(lp, create_l_link_f, list_num, num_of_lists);
} else if (arrayType == 2) {
create_l_links_array(lp, create_l_link_r, list_num, num_of_lists);
} else {
cout << "请检查你的输入";
return 0;
}
} else if (arrayType == 2) {
int arrayType;
cout << "请选择创建类型" << endl << "1,逆序头插法" << endl << "2,顺序尾插法" << endl;
cin >> arrayType;
if (arrayType == 1) {
create_d_links_array(dp, create_d_link_f, list_num, num_of_lists);
} else if (arrayType == 2) {
create_d_links_array(dp, create_d_link_r, list_num, num_of_lists);
} else {
cout << "请检查你的输入";
return 0;
}
} else {
cout << "请检查你的输入";
return 0;
}
cout << "链表元素:";
if (arrayType == 1) {
l_list_array_traverse(lp, num_of_lists); // 遍历单链表数组并打印元素
cout << endl;
} else if (arrayType == 2) {
d_list_array_traverse(dp, num_of_lists); // 遍历双链表数组并打印元素
cout << endl;
}
} else {
cout << "请检查你的输入";
return 0;
}
return 0;
}