/*!
二叉树的学习以及使用
1.使用字符串构造二叉树
2.二叉树的遍历
made by davidsu33
*/
#include <functional>
#include <stack>
#include <queue>
#include <QtDebug>
#include <QString>
#include <QCoreApplication>
using namespace std;
struct BNode
{
int m_data {-1};
BNode *m_lchild {Q_NULLPTR}, *m_rchild {Q_NULLPTR};
};
enum class VisitOrder
{
VO_PreOrder,
VO_InOrder,
VO_PostOrder,
VO_LayerOrder,
};
//typedef void (*BTREE_CALLBACK)();
typedef function<void(BNode*)> BTREE_CALLBACK;
class BTree
{
public:
explicit BTree(const char *);
~BTree();
void preOrder(BNode *n, BTREE_CALLBACK bc);
void inOrder(BNode* n, BTREE_CALLBACK bc);
void postOrder(BNode* n, BTREE_CALLBACK bc);
void layerOrder(BNode* n, BTREE_CALLBACK bc);
void dumpNode(BNode *n);
void dumpNodeByVisitOrder(BNode *n, VisitOrder vo);
void dumpTree();
void drawTree();
BNode* getRoot() const {return m_root;}
private:
void layerOrder_private(queue<BNode*> n, BTREE_CALLBACK bc);
void createTree(BNode *&n);
void releaseNode(BNode* n) ;
BNode* createNode();
char feedChar();
private:
BNode *m_root {Q_NULLPTR};
char *m_tree;
};
//==================================================
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
/*
* 如下错误写法,g是叶子节点,没有注明叶子节点的子节点
constexpr char *t = "abdh##i##e##cf##jg#";
在编写树的结构字符串的时候保证一点如果节点数是N,那么
填充的字符数目是N+1,分支数目是N-1,总共是2N,N+1相当于
是空白的区域,可以利用空白区域来建立二叉索引树。
*/
// constexpr char *t = "abdh##i##e##cf##jg###";
constexpr char *t = "ABDH##I##E##CF##G##";
BTree bt(t);
// bt.dumpTree();
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_PreOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_InOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_PostOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_LayerOrder);
return 0;
}
BTree::BTree(const char *t)
{
m_tree = strdup(t);
createTree(m_root);
Q_ASSERT(m_root);
}
BTree::~BTree()
{
postOrder(m_root, bind(&BTree::releaseNode, this, placeholders::_1));
free(m_tree);
}
void BTree::preOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
bc(n);
preOrder(n->m_lchild, bc);
preOrder(n->m_rchild, bc);
}
void BTree::inOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
inOrder(n->m_lchild, bc);
bc(n);
inOrder(n->m_rchild, bc);
}
void BTree::postOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
postOrder(n->m_lchild, bc);
postOrder(n->m_rchild, bc);
bc(n);
}
void BTree::layerOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
queue<BNode*> q;
q.push(n);
layerOrder_private(q, bc);
}
void BTree::layerOrder_private(queue<BNode*> n, BTREE_CALLBACK bc)
{
if(n.empty()) return;
queue<BNode*> nextQ;
while(!n.empty()){
BNode* node = n.front();
bc(node);
if(node->m_lchild) nextQ.push(node->m_lchild);
if(node->m_rchild) nextQ.push(node->m_rchild);
n.pop();
}
layerOrder_private(nextQ, bc);
}
void BTree::dumpNode(BNode *n)
{
qDebug()<<"node-pointer="<<n<<" node-data="<<char(n->m_data);
}
void BTree::dumpNodeByVisitOrder(BNode *n, VisitOrder vo)
{
if(!n) return;
function<void (BNode*, BTREE_CALLBACK)> f;
QString s;
switch (vo) {
case VisitOrder::VO_PreOrder:
{
s = "前序遍历";
f = bind(&BTree::preOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_InOrder:
{
s = "中序遍历";
f = bind(&BTree::inOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_PostOrder:
{
s = "后序遍历";
f = bind(&BTree::postOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_LayerOrder:
{
s = "按层遍历";
f = bind(&BTree::layerOrder, this, placeholders::_1, placeholders::_2);
break;
}
}
qDebug()<<"遍历方式:"<<s;
f(n, bind(&BTree::dumpNode, this, placeholders::_1));
}
void BTree::dumpTree()
{
preOrder(m_root, bind(&BTree::dumpNode, this, placeholders::_1));
}
void BTree::drawTree()
{
}
void BTree::createTree(BNode *& n)
{
char c = feedChar();
qDebug()<<"c="<<c;
//*******正确的情况c不可能等于字符串以外的内容*****
if(c == '#')
{
n = Q_NULLPTR;
}
else
{
n = createNode();
n->m_data = static_cast<int>(c);
createTree(n->m_lchild);
createTree(n->m_rchild);
}
}
void BTree::releaseNode(BNode *n)
{
if(n) delete n;
}
BNode *BTree::createNode()
{
BNode *n = new BNode();
return n;
}
char BTree::feedChar()
{
static int index = 0;
if(strlen(m_tree) <= index)
{
return 0;
}
return m_tree[index++];
}
二叉树的学习以及使用
1.使用字符串构造二叉树
2.二叉树的遍历
made by davidsu33
*/
#include <functional>
#include <stack>
#include <queue>
#include <QtDebug>
#include <QString>
#include <QCoreApplication>
using namespace std;
struct BNode
{
int m_data {-1};
BNode *m_lchild {Q_NULLPTR}, *m_rchild {Q_NULLPTR};
};
enum class VisitOrder
{
VO_PreOrder,
VO_InOrder,
VO_PostOrder,
VO_LayerOrder,
};
//typedef void (*BTREE_CALLBACK)();
typedef function<void(BNode*)> BTREE_CALLBACK;
class BTree
{
public:
explicit BTree(const char *);
~BTree();
void preOrder(BNode *n, BTREE_CALLBACK bc);
void inOrder(BNode* n, BTREE_CALLBACK bc);
void postOrder(BNode* n, BTREE_CALLBACK bc);
void layerOrder(BNode* n, BTREE_CALLBACK bc);
void dumpNode(BNode *n);
void dumpNodeByVisitOrder(BNode *n, VisitOrder vo);
void dumpTree();
void drawTree();
BNode* getRoot() const {return m_root;}
private:
void layerOrder_private(queue<BNode*> n, BTREE_CALLBACK bc);
void createTree(BNode *&n);
void releaseNode(BNode* n) ;
BNode* createNode();
char feedChar();
private:
BNode *m_root {Q_NULLPTR};
char *m_tree;
};
//==================================================
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
/*
* 如下错误写法,g是叶子节点,没有注明叶子节点的子节点
constexpr char *t = "abdh##i##e##cf##jg#";
在编写树的结构字符串的时候保证一点如果节点数是N,那么
填充的字符数目是N+1,分支数目是N-1,总共是2N,N+1相当于
是空白的区域,可以利用空白区域来建立二叉索引树。
*/
// constexpr char *t = "abdh##i##e##cf##jg###";
constexpr char *t = "ABDH##I##E##CF##G##";
BTree bt(t);
// bt.dumpTree();
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_PreOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_InOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_PostOrder);
bt.dumpNodeByVisitOrder(bt.getRoot(), VisitOrder::VO_LayerOrder);
return 0;
}
BTree::BTree(const char *t)
{
m_tree = strdup(t);
createTree(m_root);
Q_ASSERT(m_root);
}
BTree::~BTree()
{
postOrder(m_root, bind(&BTree::releaseNode, this, placeholders::_1));
free(m_tree);
}
void BTree::preOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
bc(n);
preOrder(n->m_lchild, bc);
preOrder(n->m_rchild, bc);
}
void BTree::inOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
inOrder(n->m_lchild, bc);
bc(n);
inOrder(n->m_rchild, bc);
}
void BTree::postOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
postOrder(n->m_lchild, bc);
postOrder(n->m_rchild, bc);
bc(n);
}
void BTree::layerOrder(BNode *n, BTREE_CALLBACK bc)
{
if(!n) return;
queue<BNode*> q;
q.push(n);
layerOrder_private(q, bc);
}
void BTree::layerOrder_private(queue<BNode*> n, BTREE_CALLBACK bc)
{
if(n.empty()) return;
queue<BNode*> nextQ;
while(!n.empty()){
BNode* node = n.front();
bc(node);
if(node->m_lchild) nextQ.push(node->m_lchild);
if(node->m_rchild) nextQ.push(node->m_rchild);
n.pop();
}
layerOrder_private(nextQ, bc);
}
void BTree::dumpNode(BNode *n)
{
qDebug()<<"node-pointer="<<n<<" node-data="<<char(n->m_data);
}
void BTree::dumpNodeByVisitOrder(BNode *n, VisitOrder vo)
{
if(!n) return;
function<void (BNode*, BTREE_CALLBACK)> f;
QString s;
switch (vo) {
case VisitOrder::VO_PreOrder:
{
s = "前序遍历";
f = bind(&BTree::preOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_InOrder:
{
s = "中序遍历";
f = bind(&BTree::inOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_PostOrder:
{
s = "后序遍历";
f = bind(&BTree::postOrder, this, placeholders::_1, placeholders::_2);
break;
}
case VisitOrder::VO_LayerOrder:
{
s = "按层遍历";
f = bind(&BTree::layerOrder, this, placeholders::_1, placeholders::_2);
break;
}
}
qDebug()<<"遍历方式:"<<s;
f(n, bind(&BTree::dumpNode, this, placeholders::_1));
}
void BTree::dumpTree()
{
preOrder(m_root, bind(&BTree::dumpNode, this, placeholders::_1));
}
void BTree::drawTree()
{
}
void BTree::createTree(BNode *& n)
{
char c = feedChar();
qDebug()<<"c="<<c;
//*******正确的情况c不可能等于字符串以外的内容*****
if(c == '#')
{
n = Q_NULLPTR;
}
else
{
n = createNode();
n->m_data = static_cast<int>(c);
createTree(n->m_lchild);
createTree(n->m_rchild);
}
}
void BTree::releaseNode(BNode *n)
{
if(n) delete n;
}
BNode *BTree::createNode()
{
BNode *n = new BNode();
return n;
}
char BTree::feedChar()
{
static int index = 0;
if(strlen(m_tree) <= index)
{
return 0;
}
return m_tree[index++];
}