树模板(父亲-儿子-兄弟)C++
前言:大学一年级上学期的寒假最后几天,某蒟蒻大学生对自己大学第一个寒假摆烂表示很难受,决定开始写博客督促自己,希望本学期能坚持下去。
模板树
//放入CMyTree_List.hpp文件里
//树形结构模板类
template<typename T>
class CMyTree_List //命名规范
{
private:
struct TreeNode
{ //数据域
T data;
//指针域
TreeNode* pParent;
TreeNode* pBrother;
TreeNode* pChild;
};
TreeNode* pRoot; // 根节点指针
public:
CMyTree_List();//构造
CMyTree_List(const CMyTree_List<int>& tree)
{
this->pRoot = create(tree.pRoot);
} //拷贝构造
~CMyTree_List();//析构
public:
void clear(); //清除
bool find(T const &findData);//查找
void insert(T const &insertData,T const &findData,bool isChild = true);//插入
private:
//递归核心函数
TreeNode* create(TreeNode* treeHead)
{
TreeNode* temp_root = nullptr;
if (treeHead)
{
temp_root = new TreeNode;
temp_root->data = treeHead->data;
temp_root->pChild = create(treeHead->pChild);
temp_root->pBrother = create(treeHead->pBrother);
}
return temp_root;
}
void _clear(TreeNode*& root);//*&传入的才是指针本身
TreeNode* _find(TreeNode* root, T const &findData);
};
template<typename T>
CMyTree_List<T>::CMyTree_List()
{
pRoot = nullptr;
}
template<typename T>
CMyTree_List<T>::~CMyTree_List()
{
clear();
}
template<typename T>
void CMyTree_List<T>::clear()
{
_clear(pRoot);//完成析构的内容
}
template<typename T>
void CMyTree_List<T>::_clear(TreeNode*& root)
{
if (nullptr == root)
return;
else
{
_clear(root->pBrother);
_clear(root->pChild);
delete root;
root = nullptr;
}
//如果指针为空则退出递归
}
template<typename T>
bool CMyTree_List<T>::find(T const& findData)
{
return _find(pRoot, findData);
}
//返回值是类中的结构在类外实现需要注意,
//但是它是递归函数,其实可以在类内实现(不会变成内联函数)
template<typename T>
typename CMyTree_List<T>::TreeNode* CMyTree_List<T>::_find(TreeNode*
root, T const& findData)
{
if (root)
{
if (root->data == findData)
return root;
TreeNode* tempNode = _find(root->pBrother,findData);
//不空说明找到了东西
if (tempNode)
return tempNode;
else
return _find(root->pChild, findData);
}
return nullptr;
}
template<typename T>
void CMyTree_List<T>::insert(T const& insertData,
T const& findData, bool isChild)
{
//准备一个新的节点
TreeNode* tempInsertNode = new TreeNode;
TreeNode*& tINode = tempInsertNode;//取别名
tINode->data = insertData;
tINode->pParent = nullptr;
tINode->pBrother = nullptr;
tINode->pChild = nullptr;
//开始插入
if (pRoot)
{
TreeNode* pFind = _find(pRoot, findData);
if (pFind)
{
//找到了参考节点
if (isChild)
{
if (pFind->pChild)
{
//有儿子
TreeNode* pTemp = pFind->pChild;
//从长子开始找
while (pTemp->pBrother)
{
pTemp = pTemp->pBrother;
}
//找到了最小儿子
pTemp->pBrother = tINode;
tINode->pParent = pTemp->pParent;
//认爹
}
else
{
//没儿子就当长子
pFind->pChild = tINode;
//认爹
tINode->pParent = pFind;
}
}
else
{
//兄弟处插入
TreeNode* pTemp = pFind;
while (pTemp->pBrother)
{
pTemp = pTemp->pBrother;
}
//找到了最小兄弟
pTemp->pBrother = tINode;
tINode->pParent = pTemp->pParent;//认爹
tINode->pBrother = nullptr;
}
}
else
{
//没找到参考坐标直接不插了
delete tINode;
tINode = nullptr;
return;
}
}
else
{
//空树插入
pRoot = tINode;
}
}
主函数测试
//main.cpp
#include <iostream>
#include "CMyTree_List.hpp"
using namespace std;
int main()
{
CMyTree_List<int> mt;
mt.insert(10, 0);//空树插入
mt.insert(20, 10,true);//作为10的长子(此刻也是最小的儿子)插入
mt.insert(21, 20, false);//作为20的兄弟插入
mt.insert(22, 10, true);//作为10最小的儿子插入
mt.insert(30, 100);//自定义
CMyTree_List<int> mt2(mt);//拷贝构造
cout << mt.find(22) << " " << mt.find(14) << endl;
return 0;
}
//数据结构小感想
其实算上上学期通过c学数据结构,我其实已经学了快一学期这样的时间,但是我依然还是没有掌握得很好,我究其原因就是因为刷题太少,我打算从下学期每周至少有计划的刷上三到五题(平时任务比较重,还得学习其他知识)。
其次就是我学数据结构的感想:
我的很大一个感想就是我每次编写数据结构的基本代码时,太多指针了,对于我这种掌握不牢的同学,VS总是会在某某指针处抛出异常,很多时候都会弄得我啼笑皆非(不知道用错词没)
其次就是debug对新手是一个很难的活,即使我通过设断点编译器告诉我错误,我还可能无法挽救。但是大的工程项目需要的debug功底很深,这方面应该在我们这样的基础学习阶段就多加练习
第三个就是代码风格了,数据结构的练习中有很多平时未掌握的语法问题,当然要把数据结构写清楚,还需要好的代码规范和内功,这些都是我最近能体会到的