1 #ifndef _TOU_H_ 2 #define _TOU_H_ 3 #include <iostream> 4 using namespace std; 5 #include <cstdlib> 6 7 typedef 8 struct{ 9 int key; 10 }DataType; 11 12 typedef 13 struct node{ 14 DataType data; 15 struct node *leftchild; 16 struct node *rightchild; 17 }BiTreeNode; 18 19 int search(BiTreeNode* root, DataType item)//查找算法 20 { 21 BiTreeNode * p; 22 if (root != NULL) 23 { 24 p = root; 25 while (p != NULL) 26 { 27 if (p->data.key == item.key)return 1;//查找成功 28 if (item.key > p->data.key)p = p->rightchild; 29 else p = p->leftchild; 30 } 31 } 32 return 0;//查找失败 33 } 34 35 int insert(BiTreeNode**root, DataType item)//插入算法 36 { 37 BiTreeNode* current = *root; 38 BiTreeNode* parent = NULL; 39 while (current != NULL) 40 { 41 if (current->data.key == item.key)return 0;//数据元素已经存在 42 parent = current; 43 if (current->data.key < item.key)current = current->rightchild; 44 else current = current->leftchild; 45 } 46 BiTreeNode* p; 47 p = (BiTreeNode*)malloc(sizeof(BiTreeNode)); 48 if (p == NULL) 49 { 50 cout << "空间不够" << endl; 51 exit(1); 52 } 53 54 //生成新的节点 55 p->data = item; 56 p->leftchild = NULL; 57 p->rightchild = NULL; 58 59 if (parent == NULL) 60 { 61 *root = p;//新的节点称为根节点 62 } 63 else if (item.key < parent->data.key){ 64 parent->leftchild = p;//新节点为该节点的左孩子节点 65 } 66 else 67 parent->rightchild = p;//新节点为该节点的右孩子节点 68 return 1; 69 } 70 71 void intraverse(BiTreeNode* root)//中序遍历显示二叉排序树节点信息函数 72 { 73 if (root == NULL) 74 { 75 return; 76 } 77 if (root->leftchild!= NULL) 78 { 79 intraverse(root->leftchild); 80 } 81 cout << " " << root->data.key; 82 if (root->rightchild != NULL) 83 { 84 intraverse(root->rightchild); 85 } 86 } 87 #endif
1 #include "tou.h" 2 #include <iostream> 3 using namespace std; 4 5 void main() 6 { 7 DataType test[] = { 4, 5, 7, 2, 1, 9, 8, 11, 3 }, x = { 9 }; 8 int n = 9; 9 BiTreeNode *root = NULL; 10 for (int i = 0; i < n; i++) 11 { 12 insert(&root, test[i]); 13 } 14 intraverse(root);//调用中序遍历 15 16 int s = search(root, x);//调用查找函数 17 if (s == 1) 18 { 19 cout << "数据元素" << x.key << "存在!" << endl; 20 } 21 else 22 { 23 cout << "数据元素" << x.key << "不存在!" << endl; 24 } 25 system("pause"); 26 return ; 27 }
注意:遍历二叉树的方法是中序遍历!好吧,我们再来说说二叉树的三种遍历方式:
1、前序遍历:(1)访问根节点(2)按照前序遍历左子树(3)按照先序遍历右子树
void proorder(bitree root)//先序遍历 { if(root) { visit(root->data);//访问根节点 proorder(root->lchild);//先序遍历左子树 proorder(root->rchild);//先序遍历右子树 } }
2、中序遍历:(1)按照中序遍历左子树(2)访问根节点(3)按照中序遍历右子树
void inorder(bitree root)//先序遍历 { if(root) { inorder(root->lchild);//先序遍历左子树 visit(root->data);//访问根节点 inorder(root->rchild);//先序遍历右子树 } }
3、后序遍历:(1)按照后序遍历左子树(2)按照后序遍历右子树(3)访问根节点
void postorder(bitree root)//先序遍历 { if(root) { postorder(root->lchild);//先序遍历左子树 postorder(root->rchild);//先序遍历右子树 visit(root->data);//访问根节点 } }
上述算法语句简单,结构清晰,非常便于形式上的掌握。注意的是,递归遍历时一定要按约定的次序访问每一个局部变量的子树。形式上,三种遍历算法的区别仅表现在visit函数的位置不同,但由于对子树的遍历是递归是递归调用,所以三种遍历的结果差别是很大的。
递归算法的时间复杂度:对于有n个节点的二叉树,设访问每个节点的时间是常量级的,则上述二叉树递归遍历的三个算法的时间复杂度是O(n),其中,对每个节点都要经过递归调用,和递归退出的控制处理过程。