【数据结构1】(查询二叉树的实现)

来源:互联网 发布:linux pv命令 编辑:程序博客网 时间:2024/06/06 12:43

理论解释:

http://www.cnblogs.com/skywang12345/p/3576328.html

很详细。不过函数实现略微复杂,不容易看懂。


函数实现:

http://www.cnblogs.com/elleniou/archive/2012/05/03/2480042.html

简单清晰。不过注释比较少,要认真看一会。


本人所用的测试代码是基于第二个链接,详细的步骤解释,参看代码

一、创建

#include "stdafx.h"#include <iostream>using std::cout;using std::cin;using std::endl;struct tree // 其实该结构体应该是节点(Node,很多参考资料都有Node结构体)。但是理解为子树更容易理解操作过程,所以定义为tree是别有用心的{int key; // 关键字,用于排序和查找tree* left; // 设置为指针确有妙处!tree* right;};// * 二叉查找树的类class BTree // 这个BTree的B是binary search tree的B{public:tree* root;BTree(){ root = NULL; } // 初始化void create_bstree(int);void printTree(tree* subtree);};// * 类函数的实现void BTree::create_bstree(int key){tree* new_node = new tree; // 使用new申请内存空间new_node->key = key; // 将新输入的数值包装成一个子树new_node->left = new_node->right = NULL;/* 判断当前的数是不是空树 */if( root == NULL )root = new_node;else // 不是空树则开始比较数值,判断新输入 new_node 的合适位置{tree* back = NULL;tree* current = root; // 指针current指向了root,current的修改都会影响到root,两个指针都是指向这个地址   //(不是两指针相等而是两个指针指向的内容相等)while(current!=NULL) // 判断new_node需要放置的节点(此刻还是叶子)        {back = current; // 控制循环次数if(current->key > key) // 应该是左侧current = current->left;elsecurrent = current->right;}// 获得if(back->key >key) // 决定new_node的左右位置back->left = new_node;elseback->right = new_node;}}// * 显示函数(有些不太直观,不过可以证明,树已经建立)void printTree(tree* subtree){if(subtree->right != NULL && subtree->left != NULL){cout<<subtree->key<<endl;if(subtree->right->key == NULL)cout<<"右儿子 = NULL"<<endl;elsecout<<"右儿子"<<subtree->right->key<<endl;if(subtree->left->key == NULL)cout<<"左儿子 = NULL"<<endl;elsecout<<"左儿子"<<subtree->left->key<<endl;printTree(subtree->right);printTree(subtree->left);}}int _tmain(){BTree A;int array[]={7,4,2,3,15,35,6,45,55,20,1,14,56,57,58};int k;     k = sizeof(array)/sizeof(array[0]);cout<<"二叉树顺序: "<<endl;for(int i=0;i<k;i++){cout<<array[i]<<" ";A.create_bstree(array[i]);}   cout<<endl;printTree(A.root); // 是使用根节点来打印return 0;}


在学习二叉树的时候,我最关注的是这个数据结构是怎么存在的,数据按照规则存放在哪。

按照我的理解,数据本身无序,所以建立数据结构,需要给数包装。这个包装就是Tree结构体。

包装以后的数据,带有其他的参数变量(指针居多),用于支撑这个结构。(方便后续的数据处理)

在内存中,把数据包装,用指针建立两两间关系,数据结构就好了。


tip:

其实,显示函数的优劣很重要。但是写不出来好的也没关系。我们可以在debug下设置断点,一步步查看root里面数据的变化,就可以看到数据的层次。


二、寻找函数

寻找函数(声明部分)

// * 二叉查找树的类class BTree{public:tree* root;BTree(){ root = NULL; }void create_bstree(int);void printTree(tree*); // 可以只给出类型int getDepth(tree*,int);void setDepth(tree*);tree* find(tree* dtree, int x);private:int depth;};


寻找函数(实现部分)

// * 给元素赋值深度(可以放在create_bstree中吗?思路就不清晰了。)void BTree::setDepth(tree* Dtree){if(Dtree == NULL)cout<<"树为空!"<<endl;else{if(Dtree->left != NULL ) // 实际上函数是利用父节点来设置子节点的深度{Dtree->left->depth = Dtree->depth + 1;setDepth(Dtree->left);}if(Dtree->right != NULL ){Dtree->right->depth = Dtree->depth + 1;setDepth(Dtree->right);}}}// * 查询元素,返回其父(子树的root)// 逻辑解释:最大的困惑是if(dtree->key == x && dtree != NULL)似乎是更合适的条件,相等,而且非空。//           其实不然。相等自然没错,但是“&& 非空”的条件,想想当迭代一直到树叶的时候会怎么样?//           条件不成立,去执行 dtree->key,这时候就会发生内存读取错误。因为这时候的dtree是NULL!/*tree* BTree::find(tree* dtree, int x){if(dtree->key == x || dtree == NULL) return dtree;else if(dtree->key < x) //往右寻找return find(dtree->right,x);else // 往左寻找return find(dtree->left,x);}*/// 改进后的,增加外来元素的判断,外来元素返回NULLtree* BTree::find(tree* dtree, int x){if(dtree->key == x) return dtree;else if(dtree->key < x) //往右寻找{if(dtree->right != NULL)return find(dtree->right,x);elsereturn NULL;}else // 往左寻找{if(dtree->left != NULL)return find(dtree->left,x);elsereturn NULL;}}// * 查询深度(要先执行setDepth() )int BTree::getDepth(tree* dtree, int x){tree* result = BTree::find(dtree,x);if(result != NULL)return result->depth;elsereturn -1; // 没有这个元素}

调用示例

cout<<"100的深度是"<<A.getDepth(A.root,55)<<endl;

同样可以在

三、三种遍历

可以参看连接2

1.先序遍历

2.中序遍历

3.后序遍历





0 0
原创粉丝点击