转自:http://blog.csdn.net/XTCGCH/article/details/70257831?locationNum=4&fps=1
摘要:本文讲解了如何使用C++实现了二叉树的创建,添加节点,删除节点,使用递归和非递归方法分别进行前中后遍历,进行层遍历
关键字 :二叉树遍历
- 二叉树的结构体
- 二叉树的建立
- 二叉树的递归遍历
- 二叉树的非递归遍历
- 源代码
二叉树的结构体
typedef struct node{ int key, visited = 0; struct node *lChild, *rChild;}Node, *BST;
这里key是存储节点的值,visited用来辅助判断节点是否被访问,在递归后序遍历时用到。
二叉树的建立
void createBST(Node * &T, int a[], int n){ T = NULL; int i; for(i = 0; i < n; i++) { BSTInsert(T, a[i]); }}
T是根节点,a[]存储节点的值,n是节点的个数
其中BSTInsert(T, a[i])函数的实现如下:
bool BSTInsert(Node * &p, int element){ if(NULL == p) { p = new Node; p->key = element; p->lChild = p->rChild = NULL; return true; } if(element == p->key) return false; if(element < p->key) return BSTInsert(p->lChild, element); return BSTInsert(p->rChild, element); }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
二叉树的递归遍历
前序遍历
void preOrderTraverse(BST T){ BST p = T; if(p) { cout << p->key << " "; preOrderTraverse(p->lChild); preOrderTraverse(p->rChild); }}
中序遍历
// 中序遍历 void midOrderTraverse(BST T){ if(T) { midOrderTraverse(T->lChild); cout << T->key << " "; midOrderTraverse(T->rChild); }}
后序遍历
// 后序遍历 void backOrderTraverse(BST T){ if(T) { backOrderTraverse(T->lChild); backOrderTraverse(T->rChild); cout << T->key << " "; }}
删除节点
//删除二叉树中与key值相等的节点bool DeleteBST(BST & T, int key){ /* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素节点 */ /* 并返回TRUE;否则返回FALSE */ if(!T) return false; /* 不存在关键字等于key的数据元素 */ else { if(key == T->key) Delete(T); else if(key < T->key) return DeleteBST(T->lChild, key); else return DeleteBST(T->rChild, key); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
DeleteBST()的作用是寻找节点值和key值相等的节点,Delete(T)才是真正删除节点的函数。代码如下:
int Delete(BST & p){ BST q, s; if(!p->lChild && !p->rChild) p = 0; else if(!p->lChild) { q = p; p = p->rChild; free(q); } else if(!p->rChild) { q = p; p = p->lChild; free(q); } else { q = p; s = p->lChild; while(s->rChild) { q = s; s = s->rChild; } p->key = s->key; if(q != p) q->rChild = s->lChild; else q->lChild = s->lChild; free(s); } return true;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
删除节点要遵循以下规则:
(1)删除节点为叶节点,直接删除;否则,执行步骤(2)
(2)当删除节点的右子树为空时,直接把左子树的根节点作为删除节点的左孩子;否则,执行步骤(3);
(3)当删除节点的左子树为空时,直接把右子树的根节点作为删除节点的右孩子;否则,执行步骤(4);
(4)当左子树和右子树都不为空时,设删除节点为p节点,先寻找p节点的左孩子,设为s节点,若s存在右孩子,执行步骤a;否则,执行步骤b;
a.以s节点为起始点,一直寻找s的最右端孩子,设为s节点,s节点的父节点设为q节点。此时把s的左子树作为q节点的右子树,s节点直接替代p节点;
b.p节点的右子树作为s节点的右子树,并且用s节点替换p节点。
步骤图解如下:
1.树的原图
2.执行规则(1)
删除叶子节点7,则直接删除
3.执行规则(2)
删除值为5的节点,由于该节点右子树为空,只需把节点5的左子树作为父节点6的左子树,然后删除节点5。
4.执行规则(3)
删除值为11的节点,由于该节点左子树为空,只需把节点11的右子树作为父节点10的右子树,然后删除节点11。
5.执行规则(4)a条例
删除值为10的节点,由于节点10的第一个左孩子6存在右子树,故寻找节点6的最右端孩子节点,为9,把节点9的左子树作为父节点6的右子树,并且以节点9替换要删除节点10,然后删除节点10。
6.执行规则(4)b条例
删除值为13的节点,由于节点13的第一个左孩子12不存在右子树,故把13的右子树作为12的右子树,以节点12替代节点13,删除节点13。
二叉树的非递归遍历
前序遍历
void preSearch(BST T){ stack<BST> s; BST p = T; while(p) { while(p) { cout << p->key << " "; s.push(p); p = p->lChild; } while(!s.empty() && !p) { p = s.top(); s.pop(); p = p->rChild; } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
中序遍历
void midSearch(BST T){ BST p = T; stack<BST> s; while(p) { while(p) { s.push(p); p = p->lChild; } while(!s.empty() && !p) { p = s.top(); cout << p->key << " "; s.pop(); p = p->rChild; } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
后序遍历
void backSearch(BST T){ BST cur; BST pre = NULL; s.push(T); while(!s.empty()) { cur = s.top(); if((cur->lChild == NULL&&cur->rChild == NULL) || (pre != NULL && (pre == cur->lChild || pre == cur->rChild))) { cout << cur->key << " "; s.pop(); pre = cur; } else { if(cur->rChild != NULL) s.push(cur->rChild); if(cur->lChild != NULL) s.push(cur->lChild); } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
层序遍历
void levelOrderTraverse(BST T){ BST p = T; if(p) { de.push_back(p); } while(!de.empty()) { p = de.front(); if(p->lChild) { de.push_back(p->lChild); } if(p->rChild) { de.push_back(p->rChild); } p = de.front(); cout << p->key << " "; de.pop_front(); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
源代码
#include <iostream> #include <deque>#include <stack>using namespace std;typedef struct node{ int key, visited = 0; struct node *lChild, *rChild;}Node, *BST;deque<BST> de;stack<BST> s;bool BSTInsert(Node * &p, int element){ if(NULL == p) { p = new Node; p->key = element; p->lChild = p->rChild = NULL; return true; } if(element == p->key) return false; if(element < p->key) return BSTInsert(p->lChild, element); return BSTInsert(p->rChild, element); }void createBST(Node * &T, int a[], int n){ T = NULL; int i; for(i = 0; i < n; i++) { BSTInsert(T, a[i]); }}#pragma region 递归void preOrderTraverse(BST T){ BST p = T; if(p) { cout << p->key << " "; preOrderTraverse(p->lChild); preOrderTraverse(p->rChild); }}void midOrderTraverse(BST T){ if(T) { midOrderTraverse(T->lChild); cout << T->key << " "; midOrderTraverse(T->rChild); }}void backOrderTraverse(BST T){ if(T) { backOrderTraverse(T->lChild); backOrderTraverse(T->rChild); cout << T->key << " "; }}int Delete(BST & p){ BST q, s; if(!p->lChild && !p->rChild) p = 0; else if(!p->lChild) { q = p; p = p->rChild; free(q); } else if(!p->rChild) { q = p; p = p->lChild; free(q); } else { q = p; s = p->lChild; while(s->rChild) { q = s; s = s->rChild; } p->key = s->key; if(q != p) q->rChild = s->lChild; else q->lChild = s->lChild; free(s); } return true;}bool DeleteBST(BST & T, int key){ if(!T) return false; else { if(key == T->key) Delete(T); else if(key < T->key) return DeleteBST(T->lChild, key); else return DeleteBST(T->rChild, key); }}#pragma endregion#pragma region 非递归void levelOrderTraverse(BST T){ BST p = T; if(p) { de.push_back(p); } while(!de.empty()) { p = de.front(); if(p->lChild) { de.push_back(p->lChild); } if(p->rChild) { de.push_back(p->rChild); } p = de.front(); cout << p->key << " "; de.pop_front(); }}void preSearch(BST T){ stack<BST> s; BST p = T; while(p) { while(p) { cout << p->key << " "; s.push(p); p = p->lChild; } while(!s.empty() && !p) { p = s.top(); s.pop(); p = p->rChild; } }}void midSearch(BST T){ BST p = T; stack<BST> s; while(p) { while(p) { s.push(p); p = p->lChild; } while(!s.empty() && !p) { p = s.top(); cout << p->key << " "; s.pop(); p = p->rChild; } }}void backSearch(BST T){ BST cur; BST pre = NULL; s.push(T); while(!s.empty()) { cur = s.top(); if((cur->lChild == NULL&&cur->rChild == NULL) || (pre != NULL && (pre == cur->lChild || pre == cur->rChild))) { cout << cur->key << " "; s.pop(); pre = cur; } else { if(cur->rChild != NULL) s.push(cur->rChild); if(cur->lChild != NULL) s.push(cur->lChild); } }}#pragma endregionint main(void){ int a[11] = { 10,6,11,5,9,13,4,8,12,14,7}; int n = 11; BST T; createBST(T, a, n); cout << "前序遍历:" << endl; preOrderTraverse(T); cout << endl; preSearch(T); cout << endl; cout << "中序遍历:" << endl; midOrderTraverse(T); cout << endl; midSearch(T); cout << endl; cout << "后序遍历:" << endl; backOrderTraverse(T); cout << endl; backSearch(T); cout << endl; cout << "层序遍历:" << endl; levelOrderTraverse(T); cout << "删除2之后" << endl; DeleteBST(T, 2); levelOrderTraverse(T); cout << endl; return 0;}