1 数据结构定义:
typedef char BTElemType;
typedef struct BiTNode {
BTElemType data;
struct BiTNode *lChild;
struct BiTNode *rChild;
}BiTNode, *BiTree;
2 功能函数定义:
定义这些功能函数很方便后续二叉树功能代码的编写。这里统一做一些介绍。
//create visit print
void CreateTree(BiTree& T);//创建二叉树
void visit(BiTNode *T);//访问节点
void Error();//参数为空时的校验--比较简便
void PrintResult(const char* str, void (*func)(BiTNode*), BiTree T);//带有格式的打印二叉树
//pre order create tree
void CreateTree(BiTree& T) {
char c;
std::cin >> c;
if (c == '#') {
T = nullptr;
} else {
T = new BiTNode();
T->data = c;
CreateTree(T->lChild);
CreateTree(T->rChild);
}
}
void visit(BiTNode *T) {
std::cout << T->data << " ";
}
void Error() {
cout << endl << "error parameter. " << endl;
}
void PrintResult(const char* str, void (*func)(BiTNode*), BiTree T) {
cout << str << ": ";
func(T);
cout << endl;
}
3 先序
a 递归
void PreOrder(BiTree T) {
if (T) {
visit(T);
PreOrder(T->lChild);
PreOrder(T->rChild);
}
}
b 非递归1
void PreOrder_2(BiTree T) {
if (!T) {
std::cout << "error argument" << endl;
return;
}
std::stack<BiTNode*> st;
st.push(T);
BiTNode *elem;
while (!st.empty()) {
elem = st.top();
st.pop();
visit(elem);
if (elem->rChild) { //right hand push first
st.push(elem->rChild);
}
if (elem->lChild) {
st.push(elem->lChild);
}
}
}
c 非递归2
void PreOrder_3(BiTree T) {
if (nullptr == T) {
std::cout << "error argument" << endl;
return;
}
std::stack<BiTNode*> st;
BiTNode *p = T;
while (p || !st.empty()) {
if (p) {
visit(p);
st.push(p);
p = p->lChild;
} else {
p = st.top();
st.pop();
p = p->rChild;
}
}
}
4 中序
a 递归
void InOrder(BiTree T) {
if (T) {
InOrder(T->lChild);
visit(T);
InOrder(T->rChild);
}
}
b 非递归
void InOrder_2(BiTree T) {
if (!T) {
return;
}
std::stack<BiTNode*> st;
BiTNode *p = T;
while (p || !st.empty()) {
if (p) {
st.push(p);
p = p->lChild;//向左走到底
} else {
p = st.top();
st.pop();
visit(p);
p = p->rChild;
}
}
}
5 总结
1 递归代码是经典的格式,很容易编写。但仅仅写递归代码不足以了解整个遍历过程。
2 要想具体了解遍历过程,写非递归代码是最好的方式,同时也能增强对于递归的理解和应用能力。
3 本节代码比较简单,也比较基础,算是为后续实现功能做准备。