1,二叉树是一种树形结构,其特点是每个节点至多只有两个子树,并且二叉树是有序树,左右子树不能颠倒。
2,二叉树和度为2的树有什么区别?
1)度为2的树至少有3个结点,而二叉树可以为空
2)度为2的有序树的孩子结点的左右次序是相对于另一个孩子而言的,如果某个结点只有一个孩子结点,这个孩子结点就无须区分其左右次序,而二叉树无论其孩子树是否是2,均需确定其左右次序。
3,二叉树的结点结构:
struct BiTNode{
BiTNode * left;
BiTNode * right;
int data;
};
4,二叉树的创建
由中序和前序遍历简历二叉树:
BiTNode * createTree(int pre[], int in[], int n){
if(n <= 0){
return NULL;
}
int i = 0;
while(i < n){
if(in[i] == pre[0]){
break;
}
i++;
}
BiTNode* root = new BiTNode;
root -> data = pre[0];
root -> left = creatTree(pre + 1, in, i);
root -> right = creatTree(pre + 1 + i, in + i + 1, n - i - 1);
return root;
}
5,二叉树的遍历
递归先序遍历二叉树
void PreOrder(const BiTNode* ptr){
if(ptr != NULL){
cout << ptr -> data << " ";
PreOrder(ptr -> left);
PreOrder(ptr -> right);
}
}
递归中序遍历二叉树
void InOrder(const BiTNode* ptr){
if(ptr != NULL){
InOrder(ptr -> left);
cout << ptr -> data << " ";
InOrder(ptr -> right);
}
}
递归后序遍历二叉树
void PostOrder(const BiTNode* ptr){
if(ptr != NULL){
PostOrder(ptr -> left);
PostOrder(ptr -> right);
cout << ptr -> data << " ";
}
}
非递归先序遍历二叉树
//1,将第一个结点入栈
//2,取出栈中第一个结点temp,访问,弹栈,如果temp -> right 不空,压栈
//3,如果temp -> left 不空,压栈
//重复2,3步知道栈空
void PreOrder(const BiTNode* ptr){
if(ptr == NULL){
return;
}
const BiTNode* temp = ptr;
stack<const BiTNode*> stc;
stc.push(temp);
while(!stc.empty()){
temp = stc.top();
cout << temp -> data << " ";
stc.pop();
if(temp -> right != NULL){
stc.push(temp -> right);
}
if(temp -> left != NULL){
stc.push(temp -> left);
}
}
}
非递归中序遍历二叉树
//1. 如果当前节点不为空,把当前节点PUSH
//2. 当前节点指向左孩子
//3. 如果当前节点为空,POP,并打印,把右节点设为当前节点
void InOrder(const BiTNode* ptr){
if(ptr == NULL){
return;
}
const BiTNode* trans = ptr;
stack<const BiTNode*> stc;
while(!stc.empty() || trans != NULL){
if(trans != NULL){
stc.push(trans);
trans = trans -> left;
}else{
const BiTNode* temp = stc.top();
cout << temp -> data << " ";
stc.pop();
trans = temp -> right;
}
}
}
非递归后序遍历二叉树(使用一个栈)
//如果用一个栈实现。我们需要先定位到该树的最左子节点。
//关键问题是,对于一个结点,如何判断该节点的状态,是
//①啥都没打印,往左打印 (处理左子树) 还是
//②左子树已经打印完毕,往右打印 (处理右子树) 还是
//③左右子树都已打印完毕,打印自己再网上
//需要一个辅助变量pre表示上一个打印的结点。令当前结点为cur,
//对①,cur 的左孩子不为null,且pre不等于cur的左孩子和右孩子
//对②,cur的右孩子不为null,且pre不等于cur的右孩子
//对③,其他情况。
void PostOrder(const BiTNode* ptr){
if(ptr == NULL){
return;
}
const BiTNode* pre = NULL;
const BiTNode* cur = ptr;
stack<const BiTNode*> stc;
stc.push(cur);
while(!stc.empty()){
cur = stc.top();
if(cur -> left != NULL && pre != cur -> left && pre != cur -> right){
stc.push(cur -> left);
}else if(cur -> right != NULL && pre != cur -> right){
stc.push(cur -> right);
}else{
pre = stc.top();
cout << pre -> data << " ";
stc.pop();
}
}
}
非递归先序遍历二叉树(使用两个栈)
//1,将根节点入栈stc
//2,取出stc中的栈顶元素temp,并把这个元素压入stc_out
//3,如果temp -> left 不空,压栈;如果temp -> right 不空,压栈;
//4,重复2,3步知道stc为空
//5,输出stc_out的内容及为后序遍历的结果
void PostOrder(const BiTNode* ptr){
if(ptr == NULL){
return;
}
stack<const BiTNode* > stc;
stack<const BiTNode* > stc_out;
stc.push(ptr);
while(!stc.empty()){
const BiTNode* temp = stc.top();
stc_out.push(temp);
stc.pop();
if(temp -> left != NULL){
stc.push(temp -> left);
}
if(temp -> right != NULL){
stc.push(temp -> right);
}
}
while(!stc_out.empty()){
cout<< stc_out.top() -> data << " ";
stc_out.pop();
}
}
层次遍历二叉树
void LevelOrder(const BiTNode* ptr){
queue<const BiTNode*> _queue;
_queue.push(ptr);
while(!_queue.empty()){
const BiTNode* temp = _queue.front();
_queue.pop();
cout << temp -> data << " ";
if(temp -> left != NULL){
_queue.push(temp -> left);
}
if(temp -> right != NULL){
_queue.push(temp -> right);
}
}
}