使用二叉链表存储的二叉树很容易施加基于递归的算法,但有一个问题就是定位是很不好处理的问题,例如找某一个节点,查找某一个节点的父节点,记录从根节点到某一个节点的路径等。
最近几天没有时间把自己写的代码整理出来,这里给出一部分,测试代码不给出(自己建测试的树太没有技术含量了:)),有兴趣的可以自己构建一棵测试的树。树节点的数据结构为:
struct binary_tree_node { binary_tree_node* _lchild; binary_tree_node* _rchild; int _value;
binary_tree_node():_lchild(NULL),_rchild(NULL),_value(-1){ }; binary_tree_node(int val):_lchild(NULL),_rchild(NULL),_value(val){ }; };
typedef binary_tree_node* node; |
定位一个节点递归实现为:
node FindNode(const node root,int val) { node n = root; if (NULL == n) return NULL;
if (n->_value == val) return n;
node p = FindNode(n->_lchild,val); if (NULL == p) return FindNode(n->_rchild,val); else return p; } |
定位一个节点非递归实现为(因为上面的递归实现是一个伪递归,使用堆栈很容易改成非递归:)):
node FindNode2(const node root,int val) { if (NULL == root) return NULL;
stack<node> tree; tree.push(root);
node n = NULL;
while (!tree.empty()) { n = tree.top(); tree.pop();
if (n->_value != val) { if (n->_rchild != NULL) tree.push(n->_rchild);
if (n->_lchild != NULL) tree.push(n->_lchild); } else { return n; } }
return NULL; } |
输出到当前节点的所有路径,也就是当前节点的所有父亲节点集合(这个很有用的,呵呵,知道的人自然知道:))。这个实现其实是根据中序遍历得到的,采用中序遍历的方式查找节点,当查找到当前节点的时候堆栈中保存的就是当前节点以及当前节点的所有父亲节点。实现代码为:
int* GetParent(const node root,int val) { assert(NULL != root); if (root->_value == val) { cout<<“found: “<<root->_value<<endl; int* prt = new int(root->_value); return prt; }
stack<node> tree; node n = root; node tmp = NULL;
while ((!tree.empty()) || (NULL != root)) { while (n != NULL) { tree.push(n); n = n->_lchild; }
if (!tree.empty()) { int len = tree.size(); int* prt = new int[len]; int i = 0;
tmp = tree.top(); if (tmp->_value == val) { while (tree.size() > 0) { prt[i++] = tree.top()->_value; cout<<tree.top()->_value<<“->”; tree.pop(); } cout<<endl;
return prt; } else n = n->_rchild; } }
return NULL; } |