【编程珠玑】
看珠玑看了一半了,多是趁着闲着的时候看上几页,思考一下后面的问题。珠玑很薄,才两百来页,但是里面的一些技术却十分地实用,改天一定要好好整理一下,将写的程序和一些有趣的技术(编程思想,断言,数据表现形式)等话题展开探讨。很久没有写技术性的文字了,只是拿来简单的二叉查找树来练练手。
【二叉查找树】
二叉查找树是一种二叉树,由于其具有左子树的元素都小于根节点,右子树元素大于根节点的这种特性,故而使得查找起来的复杂度是O(lgN)。这种结构编码十分简单,而且效率很高,占用空间少,非常受欢迎。
首先定义一个节点数据结构,拥有一个value和左右孩子指针。
#include <iostream>
using namespace std;
class Node
{
public:
int value;
Node* leftChild;
Node* rightChild;
public:
Node(int i) {value = i;leftChild = NULL;rightChild = NULL;}
};
下面就是一个递归的插入算法,十分地巧妙:
#include <iostream>
#include "Node.h"
#include <stdlib.h>
#include <time.h>
using namespace std;
//二叉查找树
Node* insert(Node* p,int element);
void traverse(Node* p);
void search(int element,Node *p);
void main()
{
//Node *root = new Node(0);
//insert element into the tree
srand(clock());
Node *root = new Node(rand()%100);
for(int i=1;i<20;i++)
{
insert(root,rand()%100);
}
traverse(root);
int element ;
cin >> element;
search(element,root);
system("pause");
}
Node* insert(Node* p,int element)
{
if(p==NULL)
p= new Node(element);
else if(element < p->value)
{
p->leftChild = insert(p->leftChild,element);
}
else if(element >= p->value)
{
p->rightChild = insert(p->rightChild,element);
}
return p;
}
void traverse(Node* p) //中序遍历
{
if(p == NULL)
return;
traverse(p->leftChild);
cout << p->value << endl;
traverse(p->rightChild);
return;
}
其中插入算法的原理是如果该元素已经找到所在位置,即叶子处(条件p==NULL),否则如果小于根节点,说明要往左子树插入,递归调用insert函数。同理,如果大于或者等于根节点,则往右子树插入,递归调用insert函数。我们跟踪一次插入,假如有一棵树,如图所示,一开始是空的。
要插入元素5,由于p==NULL,故新建一个节点,插入。而要插入元素3,则满足条件二element<p->value,故而递归调用insert函数,往左子树插入,接着情况和在一颗空树中插入节点一样,插入节点后返回的是p的指针赋给5的左孩子。故而后面两步也很好理解了。递归的好处就在于,将情况都抽象出来了,编程会变得简单很多。
一颗树构造好之后,就要发挥它的目标功能了——>查找。使用递归定义的中序遍历,我们可以让整棵树从小道大的序列输出。当然我们的查找也非常简单了,假如我们要查找元素6,先从根部出发,因为6>5,故应该在右子树中找,而在右子树中,6<8,在左子树中找,找到了。如果找到null指针,则说明该元素不在二叉查找树中。
下面是查找的代码:
void search(int element,Node *p)
{
if(p==NULL)
return; //元素不在树中
if(element== p->value)
cout << "found "<<element<<endl;
else if(element < p->value)//左子树递归查找
search(element,p->leftChild);
else //if element > p->value 右子树递归查找
search(element,p->rightChild);
}
【小结】
由于树的递归结构,我们可以很方便地使用递归的思想,而我们也可能为了效率而避免使用递归,而使用迭代的方法提高效率。还是继续看珠玑吧。
by bibodeng 2012-05-17 原载于bibodeng think beyond
转载于:https://blog.51cto.com/bibodeng/866877