树  0.1
数据结构_第6章
ch6_5.cc
Go to the documentation of this file.
1 
14 #include "binaryTree.hh"
15 #include <ctime>
16 #include <fstream>
17 #include <string>
18 
19 // 常量定义
20 const std::string data_file_name("ch6_5.result");
21 
36 static bool GenTreeData(const char *_file_path = "./test0.txt", const char *empty_flag = "@");
37 
48 template <typename T, typename Comparator>
49 static void print_test_result(const Tree::binaryTree<T, Comparator> &tree_original, const typename Tree::binaryTree<T, Comparator>::value_type &flag, std::ostream &out = std::cout);
50 
51 int main(int argc, char const *argv[])
52 {
53  // time
54  clock_t t = clock();
55  time_t rawtime;
56  struct tm *timeinfo;
57 
58  time(&rawtime); // Get the current calendar time
59  timeinfo = localtime(&rawtime); // Convert time_t to tm as local time
60 
61  // 获取文件路径,参考:http://www.cplusplus.com/reference/string/string/find_last_of/
62  const std::string full_path_exec{argv[0]};
63  std::string::size_type found = full_path_exec.find_last_of("/\\", std::string::npos);
64  const std::string exec_path = full_path_exec.substr(0, found + 1);
65  const std::string exec_filename = full_path_exec.substr(found + 1, std::string::npos);
66 
67  // 生成数据文件,然后从文件中读取数据,依此建立一棵二叉树
68  std::string data_file_full_path{exec_path + data_file_name}; // 数据文件的绝对地址
69 
70  // 生成数据文件
71  if (!GenTreeData(data_file_full_path.c_str(), "@"))
72  {
73  std::cout << "文件:" << data_file_full_path << "生成失败!\n";
74  return 1;
75  }
76 
77  // 读数据文件
78  std::ifstream fin(data_file_full_path.c_str(), std::ios_base::in);
79  if (fin.fail())
80  {
81  std::cout << "文件:" << data_file_full_path << "读取失败!\n";
82  return 1;
83  }
84 
85  // 建立二叉树
86  Tree::binaryTree<std::string> tree_original{};
87  tree_original.createTree("@", fin);
88  fin.close();
89 
90  // 准备将结果写入数据文件
91  std::ofstream fout(data_file_full_path.c_str(), std::ios_base::app);
92  if (fout.fail())
93  {
94  std::cerr << "文件:" << data_file_full_path << "写入失败!\n";
95  return 1;
96  }
97 
98  // printf("Current local time and date: %s\n", asctime(timeinfo)); // Convert tm structure to string
99  std::cout << "\nCurrent local time and date: " << asctime(timeinfo) << '\n';
100  fout << "\nCurrent local time and date: " << asctime(timeinfo) << '\n';
101 
102  print_test_result(tree_original, "@", std::cout);
103  print_test_result(tree_original, "@", fout);
104 
105  // ch6_1
106  Tree::binaryTree<std::string> temp_tree = tree_original;
107  temp_tree.swaplr();
108  auto tree_swaplr = temp_tree;
109  std::cout << "\n交换左右结点后:\n";
110  fout << "\n交换左右结点后:\n";
111  print_test_result(tree_swaplr, "@", std::cout);
112  print_test_result(tree_swaplr, "@", fout);
113 
114  // ch6_3, ch6_4
115  temp_tree.delLeft("G");
116  temp_tree.delRight("G");
117  auto tree_swaplr_and_prune = temp_tree;
118  std::cout << "\n剪枝后:\n";
119  fout << "\n剪枝后:\n";
120  print_test_result(tree_swaplr_and_prune, "@", std::cout);
121  print_test_result(tree_swaplr_and_prune, "@", fout);
122 
123  // ch6_5
124  std::cout << "\ntree_swaplr == tree_swaplr_and_prune?\n"
125  << std::boolalpha << (tree_swaplr == tree_swaplr_and_prune);
126  fout << "\ntree_swaplr == tree_swaplr_and_prune?\n"
127  << std::boolalpha << (tree_swaplr == tree_swaplr_and_prune);
128  std::cout << "\ntree_original == tree_swaplr_and_prune?\n"
129  << std::boolalpha << (tree_original == tree_swaplr_and_prune);
130  fout << "\ntree_original == tree_swaplr_and_prune?\n"
131  << std::boolalpha << (tree_original == tree_swaplr_and_prune);
132  std::cout << "\ntree_original == tree_swaplr?\n"
133  << std::boolalpha << (tree_original == tree_swaplr);
134  fout << "\ntree_original == tree_swaplr?\n"
135  << std::boolalpha << (tree_original == tree_swaplr);
136  std::cout << "\ntree_original == tree_original?\n"
137  << std::boolalpha << (tree_original == tree_original);
138  fout << "\ntree_original == tree_original?\n"
139  << std::boolalpha << (tree_original == tree_original);
140  std::cout << "\ntree_swaplr == tree_swaplr?\n"
141  << std::boolalpha << (tree_swaplr == tree_swaplr);
142  fout << "\ntree_swaplr == tree_swaplr?\n"
143  << std::boolalpha << (tree_swaplr == tree_swaplr);
144  std::cout << "\ntree_swaplr_and_prune == tree_swaplr_and_prune?\n"
145  << std::boolalpha << (tree_swaplr_and_prune == tree_swaplr_and_prune);
146  fout << "\ntree_swaplr_and_prune == tree_swaplr_and_prune?\n"
147  << std::boolalpha << (tree_swaplr_and_prune == tree_swaplr_and_prune) << '\n';
148 
149  t = clock() - t;
150  // printf("\nIt took me %ld clicks (%f seconds).\n", t, ((float)t) / CLOCKS_PER_SEC);
151  std::cout << "\nIt took me " << t << " clicks (" << ((float)t) / CLOCKS_PER_SEC << " seconds).\n";
152  fout << "\nIt took me " << t << " clicks (" << ((float)t) / CLOCKS_PER_SEC << " seconds).\n";
153 
154  fout.close();
155  system("pause");
156  return 0;
157 }
158 
159 bool GenTreeData(const char *_file_path, const char *empty_flag)
160 {
161  std::string file_path(_file_path);
162 
163  // 调用DOS命令,询问是否删除文件
164  std::string cmd = std::string("DEL /P \"") + file_path + '"';
165  system("@echo on");
166  system("echo We are trying to delete some files, which will be created later.");
167  system("pause");
168  system(cmd.c_str());
169 
170  // 检查文件是否存在且可读
171  std::ifstream fin(file_path.c_str(), std::ios_base::in);
172  if (fin.good())
173  {
174  std::cerr << "文件已存在!\n";
175  fin.close();
176 
177  system("pause");
178  return true;
179  }
180 
181  // 文件不存在或不可读,尝试新建
182  std::ofstream fout(file_path.c_str(), std::ios_base::out);
183  if (fout.fail())
184  {
185  std::cerr << "无写权限,文件生成失败!\n";
186 
187  system("pause");
188  return false;
189  }
190  fout << "A\n"
191  << "B\tC\n"
192  << "D\tE\tF\tG\n"
193  << empty_flag << '\t' << empty_flag << '\t' << empty_flag << '\t' << empty_flag << '\t' << empty_flag << '\t' << empty_flag << '\t' << "H\tI\n"
194  << empty_flag << '\t' << empty_flag << '\t' << empty_flag << '\t' << empty_flag << std::endl;
195 
196  // 检查是否生成成功
197  if (fout.good())
198  {
199  system("echo File created successfully!");
200  fout.close();
201  system("pause");
202  return true;
203  }
204 
205  std::cerr << "无法生成文件!\n";
206  system("pause");
207  return false;
208 }
209 
210 template <class T, typename Comparator>
211 void print_test_result(const Tree::binaryTree<T, Comparator> &tree_original, const typename Tree::binaryTree<T, Comparator>::value_type &flag, std::ostream &out)
212 {
213  out << "二叉树的规模(递归 非递归):\n"
214  << tree_original.size() << ' ' << tree_original.size_loop();
215  out << "\n二叉树的高(深)度(递归 非递归),从0起:\n"
216  << tree_original.height() << ' ' << tree_original.height_loop();
217  // ch6_2
218  out << "\n度为2的结点的个数是:\n"
219  << tree_original.CountDegreeTwo();
220  // ch6_3
221  out << "\n是否为满二叉树:\n"
222  << std::boolalpha << tree_original.isFullBinaryTree();
223  // ch6_4
224  out << "\n是否为完全二叉树:\n"
225  << std::boolalpha << tree_original.isCompleteTree();
226  out << "\n前序遍历(递归):\n";
227  tree_original.preOrder(out);
228  out << "\n前序遍历(非递归):\n";
229  tree_original.preOrder_loop(out);
230  out << "\n中序遍历(递归):\n";
231  tree_original.inOrder(out);
232  out << "\n中序遍历(非递归):\n";
233  tree_original.inOrder_loop(out);
234  out << "\n后序遍历(递归):\n";
235  tree_original.postOrder(out);
236  out << "\n后序遍历(非递归):\n";
237  tree_original.postOrder_loop(out);
238  out << "\n层次遍历:\n";
239  tree_original.levelOrder(out);
240  out << "\n层次打印(调用lchild(), rchild(), root()等API):\n";
241  Tree::printBinaryTree(tree_original, flag, out);
242 }
print_test_result
static void print_test_result(const Tree::binaryTree< T, Comparator > &tree_original, const typename Tree::binaryTree< T, Comparator >::value_type &flag, std::ostream &out=std::cout)
(测试用)将二叉树类的多种方法的输出插到输出流
Definition: ch6_1.cc:175
Tree::binaryTree::swaplr
void swaplr()
交换左右子树
Definition: binaryTree.hh:404
Tree::binaryTree::isFullBinaryTree
bool isFullBinaryTree() const
是否满二叉树
Definition: binaryTree.hh:699
Tree::binaryTree::delRight
void delRight(const value_type &x)
删除右subtree
Definition: binaryTree.hh:1041
GenTreeData
static bool GenTreeData(const char *_file_path="./test0.txt", const char *empty_flag="@")
生成一个文件,内容是一棵二叉树的层次遍历
Definition: ch6_5.cc:159
Tree::binaryTree::inOrder_loop
void inOrder_loop(std::ostream &out=std::cout) const
中序遍历(非递归版本)
Definition: binaryTree.hh:848
Tree::binaryTree::value_type
T value_type
类型别名定义
Definition: binaryTree.hh:108
Tree::binaryTree::preOrder_loop
void preOrder_loop(std::ostream &out=std::cout) const
前序遍历(非递归版本)
Definition: binaryTree.hh:769
Tree::binaryTree::isCompleteTree
bool isCompleteTree() const
返回是否完全二叉树
Definition: binaryTree.hh:711
Tree::binaryTree::height_loop
size_type height_loop() const
返回二叉树的高度(非递归版本)
Definition: binaryTree.hh:1201
Tree::binaryTree::size
size_type size() const
返回二叉树的结点数(递归版本)
Definition: binaryTree.hh:1312
Tree::binaryTree::levelOrder
void levelOrder(std::ostream &out=std::cout) const
层次遍历
Definition: binaryTree.hh:990
Tree::binaryTree::inOrder
void inOrder(std::ostream &out=std::cout) const
中序遍历(递归版本)
Definition: binaryTree.hh:906
Tree::binaryTree::size_loop
size_type size_loop() const
返回二叉树的结点数(非递归版本)
Definition: binaryTree.hh:1318
Tree::binaryTree::height
size_type height() const
返回二叉树的高度(递归版本)
Definition: binaryTree.hh:1195
Tree::binaryTree::postOrder_loop
void postOrder_loop(std::ostream &out=std::cout) const
后序遍历(非递归版本)
Definition: binaryTree.hh:923
Tree::binaryTree::delLeft
void delLeft(const value_type &x)
删除左subtree
Definition: binaryTree.hh:1031
Tree::binaryTree::postOrder
void postOrder(std::ostream &out=std::cout) const
后序遍历(递归版本)
Definition: binaryTree.hh:984
main
int main(int argc, char const *argv[])
Definition: ch6_5.cc:51
Tree::binaryTree::createTree
void createTree(const value_type &flag=value_type{}, std::istream &in=std::cin)
Create a Tree object.
Definition: binaryTree.hh:1324
Tree::binaryTree::preOrder
void preOrder(std::ostream &out=std::cout) const
前序遍历(递归版本)
Definition: binaryTree.hh:831
binaryTree.hh
Tree::binaryTree
用二叉链表实现的二叉树类
Definition: binaryTree.hh:53
Tree::binaryTree::CountDegreeTwo
size_type CountDegreeTwo() const
统计树中度为2的结点的个数
Definition: binaryTree.hh:409
Tree::printBinaryTree
void printBinaryTree(const binaryTree< T, Comparator > &bin_tree, const typename binaryTree< T, Comparator >::value_type &flag, std::ostream &out=std::cout)
输出一棵二叉树
Definition: binaryTree.hh:1426
data_file_name
const std::string data_file_name("ch6_5.result")
保存测试数据的文件名