01/10/2018, 00:52
Code binary search tree của mình bị lỗi, mọi ng chạy thử coi lỗi gì giúp mình với
#include <iostream>
#include <deque>
#include <climits>
#include <vector>
using namespace std;
struct Tree
{
char data;
Tree *left;
Tree *right;
Tree *parent;
};
Tree* lookUp(struct Tree *node, char key)
{
if(node == NULL) return node;
if(node->data == key) return node;
else {
if(node->data < key)
return lookUp(node->right, key) ;
else
return lookUp(node->left, key);
}
}
Tree* leftMost(struct Tree *node)
{
if(node == NULL) return NULL;
while(node->left != NULL)
node = node->left;
return node;
}
struct Tree *newTreeNode(int data)
{
Tree *node = new Tree;
node->data = data;
node->left = NULL;
node->right = NULL;
node->parent = NULL;
return node;
}
struct Tree* insertTreeNode(struct Tree *node, int data)
{
static Tree *p;
Tree *retNode;
//if(node != NULL) p = node;
if(node == NULL) {
retNode = newTreeNode(data);
retNode->parent = p;
return retNode;
}
if(data <= node->data ) {
p = node;
node->left = insertTreeNode(node->left,data);
}
else {
p = node;
node->right = insertTreeNode(node->right,data);
}
return node;
}
void isBST(struct Tree *node)
{
static int lastData = INT_MIN;
if(node == NULL) return;
isBST(node->left);
/* check if the given tree is BST */
if(lastData < node->data)
lastData = node->data;
else {
cout << "Not a BST" << endl;
return;
}
isBST(node->right);
return;
}
int treeSize(struct Tree *node)
{
if(node == NULL) return 0;
else
return treeSize(node->left) + 1 + treeSize(node->right);
}
int maxDepth(struct Tree *node)
{
if(node == NULL || (node->left == NULL && node->right == NULL))
return 0;
int leftDepth = maxDepth(node->left);
int rightDepth = maxDepth(node->right);
return leftDepth > rightDepth ?
leftDepth + 1 : rightDepth + 1;
}
int minDepth(struct Tree *node)
{
if(node == NULL || (node->left == NULL && node->right == NULL))
return 0;
int leftDepth = minDepth(node->left);
int rightDepth = minDepth(node->right);
return leftDepth < rightDepth ?
leftDepth + 1 : rightDepth + 1;
}
bool isBalanced(struct Tree *node)
{
if(maxDepth(node)-minDepth(node) <= 1)
return true;
else
return false;
}
/* Tree Minimum */
Tree* minTree(struct Tree *node)
{
if(node == NULL) return NULL;
while(node->left)
node = node -> left;
return node;
}
/* Tree Maximum */
Tree* maxTree(struct Tree *node)
{
while(node->right)
node = node -> right;
return node;
}
/* In Order Successor - a node which has the next higher key */
Tree *succesorInOrder(struct Tree *node)
{
/* if the node has right child, seccessor is Tree-Minimum */
if(node->right != NULL) return minTree(node->right);
Tree *y = node->parent;
while(y != NULL && node == y->right) {
node = y;
y = y->parent;
}
return y;
}
/* In Order Predecessor - a node which has the next lower key */
Tree *predecessorInOrder(struct Tree *node)
{
/* if the node has left child, predecessor is Tree-Maximum */
if(node->left != NULL) return maxTree(node->left);
Tree *y = node->parent;
/* if it does not have a left child,
predecessor is its first left ancestor */
while(y != NULL && node == y->left) {
node = y;
y = y->parent;
}
return y;
}
void reverseOrderPrint(struct Tree *node)
{
if(node == NULL) return;
if(node->left == NULL && node->right == NULL) {
cout << node->data << " ";
return;
}
reverseOrderPrint(node->right);
cout << node->data << " ";
reverseOrderPrint(node->left);
}
Tree *lowestCommonAncestor(Tree *node, Tree *p, Tree *q)
{
Tree *left, *right;
if(node == NULL) return NULL;
if(node->left == p || node->left == q
|| node->right == p || node->right == q) return node;
left = lowestCommonAncestor(node->left,p,q);
right = lowestCommonAncestor(node->right, p,q);
if(left && right)
return node;
else
return (left) ? left : right;
}
void clear(struct Tree *node)
{
if(node != NULL) {
clear(node->left);
clear(node->right);
delete node;
}
}
/* print tree in order */
/* 1. Traverse the left subtree.
2. Visit the root.
3. Traverse the right subtree.
*/
void printTreeInOrder(struct Tree *node)
{
if(node == NULL) return;
printTreeInOrder(node->left);
cout << node->data << " ";
printTreeInOrder(node->right);
}
/* print tree in postorder*/
/* 1. Traverse the left subtree.
2. Traverse the right subtree.
3. Visit the root.
*/
void printTreePostOrder(struct Tree *node)
{
if(node == NULL) return;
printTreePostOrder(node->left);
printTreePostOrder(node->right);
cout << node->data << " ";
}
/* print in preorder */
/* 1. Visit the root.
2. Traverse the left subtree.
3. Traverse the right subtree.
*/
void printTreePreOrder(struct Tree *node)
{
if(node == NULL) return;
cout << node->data << " ";
printTreePreOrder(node->left);
printTreePreOrder(node->right);
}
/* In reverse of printTreeInOrder() */
void printTreeReverseOrder(struct Tree *node)
{
if(node == NULL) return;
if(node->left == NULL && node->right == NULL) {
cout << node->data << " ";
return;
}
printTreeReverseOrder(node->right);
cout << node->data << " ";
printTreeReverseOrder(node->left);
}
/* recursion routine to find path */
void pathFinder(struct Tree *node, int path[], int level)
{
if(node == NULL) return;
// save leaf node
if(node->left == NULL && node->right == NULL) {
path[level] = node->data;
for(int i = 0; i <= level; i++) {
cout << (char)path[i];
}
cout << endl;
return;
}
// save parent node
path[level] = node->data;
pathFinder(node->left, path, level+1);
pathFinder(node->right, path, level+1);
}
bool matchTree(Tree *r1, Tree *r2)
{
/* Nothing left in the subtree */
if(r1 == NULL && r2 == NULL)
return true;
/* Big tree empty and subtree not found */
if(r1 == NULL || r2 == NULL)
return false;
/* Not matching */
if(r1->data != r2->data)
return false;
return (matchTree(r1->left, r2->left) &&
matchTree(r1->right, r2->right));
}
bool subTree(Tree *r1, Tree *r2)
{
/*Big tree empty and subtree not found */
if(r1 == NULL)
return false;
if(r1->data == r2->data)
if(matchTree(r1, r2)) return true;
return
(subTree(r1->left, r2) || subTree(r1->right, r2));
}
bool isSubTree(Tree *r1, Tree *r2)
{
/* Empty tree is subtree */
if(r2 == NULL)
return true;
else
return subTree(r1, r2);
}
/* change a tree so that the roles of the left
and right hand pointers are swapped at every node */
void mirror(Tree *r)
{
if(r == NULL) return;
Tree *tmp;
mirror(r->left);
mirror(r->right);
/* swap pointers */
tmp = r->right;
r->right = r->left;
r->left = tmp;
}
/* create a new tree from a sorted array */
Tree *addToBST(char arr[], int start, int end)
{
if(end < start) return NULL;
int mid = (start + end)/2;
Tree *r = new Tree;
r->data = arr[mid];
r->left = addToBST(arr, start, mid-1);
r->right = addToBST(arr, mid+1, end);
return r;
}
Tree *createMinimalBST(char arr[], int size)
{
return addToBST(arr,0,size-1);
}
/* Breadth first traversal using queue */
void BreadthFirstTraversal(Tree *root)
{
if (root == NULL) return;
deque <Tree *> queue;
queue.push_back(root);
while (!queue.empty()) {
Tree *p = queue.front();
cout << p->data << " ";
queue.pop_front();
if (p->left != NULL)
queue.push_back(p->left);
if (p->right != NULL)
queue.push_back(p->right);
}
cout << endl;
}
/* get the level of a node element: root level = 0 */
int getLevel(struct Tree *node, int elm, int level)
{
if(node == NULL) return 0;
if(elm == node->data)
return level;
else if(elm < node->data)
return getLevel(node->left, elm, level+1);
else
return getLevel(node->right, elm, level+1);
}
/* This code prints out all nodes at the same depth (level) */
void BreadthFirst_LevelElement_Print
(struct Tree *root, vector<vector<int> > &v;)
{
if(root == NULL) return;
deque<Tree *> q;
q.push_back(root);
while(!q.empty()) {
Tree *p = q.front();
int lev = getLevel(root, p->data, 0);
v[lev].push_back(p->data);
q.pop_front();
if(p->left) q.push_back(p->left);
if(p->right)q.push_back(p->right);
}
return;
}
/* levelPrint()
prints nodes at the same level
This is simpler than the BreadthFirstTraversal(root) above
It takes 2D vector with the same size of level (= MaxDepth+1)
and fills elements as we traverse (preOrder) */
void levelPrint(struct Tree *node, vector<vector<char> >&elm;, int level)
{
if(node == NULL) return;
// leaf nodes
if(node->left == NULL && node->right == NULL) {
elm[level].push_back(node->data);
return;
}
// other nodes
elm[level++].push_back(node->data);
levelPrint(node->left, elm, level);
levelPrint(node->right, elm, level);
}
/* find n-th max node from a tree */
void NthMax(struct Tree* t)
{
static int n_th_max = 5;
static int num = 0;
if(t == NULL) return;
NthMax(t->right);
num++;
if(num == n_th_max)
cout << n_th_max << "-th maximum data is "
<< t->data << endl;
NthMax(t->left);
}
/* Converting a BST into an Array */
void TreeToArray(struct Tree *node, int a[]){
static int pos = 0;
if(node){
TreeToArray(node->left,a);
a[pos++] = node->data;
TreeToArray(node->right,a);
}
}
/* Separate even/odd level elements */
/* This function is using BFS */
void level_even_odd(struct Tree *node)
{
vector<char> evenVec, oddVec;
if (node == NULL) return;
deque<struct Tree*> que;
que.push_back(node);
while(!que.empty())
{
struct Tree *p = que.front();
int level = getLevel(node, p->data, 0) ;
// even level
if (level % 2 == 0)
evenVec.push_back(p->data);
else
oddVec.push_back(p->data);
que.pop_front();
if(p->left) que.push_back(p->left);
if(p->right) que.push_back(p->right);
}
cout << "even level elements : ";
for(int i = 0; i < evenVec.size(); i++)
cout << evenVec[i] << " ";
cout << endl << "odd level elements : ";
for(int i = 0; i < oddVec.size(); i++)
cout << oddVec[i] << " ";
cout << endl;
}
int main(int argc, char **argv)
{
char ch, ch1, ch2;
Tree *found;
Tree *succ;
Tree *pred;
Tree *ancestor;
char charArr[9]
= {'A','B','C','D','E','F','G','H','I'};
Tree *root = newTreeNode('F');
insertTreeNode(root,'B');
insertTreeNode(root,'A');
insertTreeNode(root,'D');
insertTreeNode(root,'C');
insertTreeNode(root,'E');
insertTreeNode(root,'G');
insertTreeNode(root,'I');
insertTreeNode(root,'H');
/* is the tree BST? */
isBST(root);
/* size of tree */
cout << "size = " << treeSize(root) << endl;
/* max depth */
cout << "max depth = " << maxDepth(root) << endl;
/* min depth */
cout << "min depth = " << minDepth(root) << endl;
/* balanced tree? */
if(isBalanced(root))
cout << "This tree is balanced!
";
else
cout << "This tree is not balanced!
";
/* min value of the tree*/
if(root)
cout << "Min value = " << minTree(root)->data << endl;
/* max value of the tree*/
if(root)
cout << "Max value = " << maxTree(root)->data << endl;
/* get the level of a data: root level = 0 */
cout << "Node B is at level: " << getLevel(root, 'B', 0) << endl;
cout << "Node H is at level: " << getLevel(root, 'H', 0) << endl;
cout << "Node F is at level: " << getLevel(root, 'F', 0) << endl;
/* separate even/odd level elements */
level_even_odd(root);
ch = 'B';
found = lookUp(root,ch);
if(found) {
cout << "Min value of subtree " << ch << " as a root is "
<< minTree(found)->data << endl;
cout << "Max value of subtree " << ch << " as a root is "
<< maxTree(found)->data << endl;
}
ch = 'B';
found = lookUp(root,ch);
if(found) {
succ = succesorInOrder(found);
if(succ)
cout << "In Order Successor of " << ch << " is "
<< succesorInOrder(found)->data << endl;
else
cout << "In Order Successor of " << ch << " is None
";
}
ch = 'E';
found = lookUp(root,ch);
if(found) {
succ = succesorInOrder(found);
if(succ)
cout << "In Order Successor of " << ch << " is "
<< succesorInOrder(found)->data << endl;
else
cout << "In Order Successor of " << ch << " is None
";
}
ch = 'I';
found = lookUp(root,ch);
if(found) {
succ = succesorInOrder(found);
if(succ)
cout << "In Order Successor of " << ch << " is "
<< succesorInOrder(found)->data << endl;
else
cout << "In Order Successor of " << ch << " is None
";
}
ch = 'B';
found = lookUp(root,ch);
if(found) {
pred = predecessorInOrder(found);
if(pred)
cout << "In Order Predecessor of " << ch << " is "
<< predecessorInOrder(found)->data << endl;
else
cout << "In Order Predecessor of " << ch << " is None
";
}
ch = 'E';
found = lookUp(root,ch);
if(found) {
pred = predecessorInOrder(found);
if(pred)
cout << "In Order Predecessor of " << ch << " is "
<< predecessorInOrder(found)->data << endl;
else
cout << "In Order Predecessor of " << ch << " is None
";
}
ch = 'I';
found = lookUp(root,ch);
if(found) {
pred = predecessorInOrder(found);
if(pred)
cout << "In Order Predecessor of " << ch << " is "
<< predecessorInOrder(found)->data << endl;
else
cout << "In Order Predecessor of " << ch << " is None
";
}
/* Lowest Common Ancestor */
ch1 = 'A';
ch2 = 'C';
ancestor =
lowestCommonAncestor(root,
lookUp(root,ch1), lookUp(root,ch2));
if(ancestor)
cout << "The lowest common ancestor of " << ch1 << " and "
<< ch2 << " is " << ancestor->data << endl;
ch1 = 'E';
ch2 = 'H';
ancestor =
lowestCommonAncestor(root,
lookUp(root,ch1), lookUp(root,ch2));
if(ancestor)
cout << "The lowest common ancestor of " << ch1 << " and "
<< ch2 << " is " << ancestor->data << endl;
ch1 = 'D';
ch2 = 'E';
ancestor =
lowestCommonAncestor(root,
lookUp(root,ch1), lookUp(root,ch2));
if(ancestor)
cout << "The lowest common ancestor of " << ch1 << " and "
<< ch2 << " is " << ancestor->data << endl;
ch1 = 'G';
ch2 = 'I';
ancestor =
lowestCommonAncestor(root,
lookUp(root,ch1), lookUp(root,ch2));
if(ancestor)
cout << "The lowest common ancestor of " << ch1 << " and "
<< ch2 << " is " << ancestor->data << endl;
ch1 = 'H';
ch2 = 'I';
ancestor =
lowestCommonAncestor(root,
lookUp(root,ch1), lookUp(root,ch2));
if(ancestor)
cout << "The lowest common ancestor of " << ch1 << " and "
<< ch2 << " is " << ancestor->data << endl;
/* print tree in order */
cout << "increasing sort order
";
printTreeInOrder(root);
cout << endl;
/* print tree in postorder*/
cout << "post order
";
printTreePostOrder(root);
cout << endl;
/* print tree in preorder*/
cout << "pre order
";
printTreePreOrder(root);
cout << endl;
/* print tree in reverse order*/
cout << "reverse order
";
printTreeReverseOrder(root);
cout << endl;
/* lookUp */
ch = 'D';
found = lookUp(root,ch);
if(found)
cout << found->data << " is in the tree
";
else
cout << ch << " is not in the tree
";
/* lookUp */
ch = 'M';
found = lookUp(root,ch);
if(found)
cout << found->data << " is in the tree
";
else
cout << ch << " is not in the tree
";
/* printing all paths :
Given a binary tree, print out all of its root-to-leaf
paths, one per line. Uses a recursive helper to do the work. */
cout << "printing paths ..." << endl;
int path[10];
pathFinder(root, path, 0);
/* find n-th maximum node */
NthMax(root);
/* Traversing level-order.
We visit every node on a level before going to a lower level.
This is also called Breadth-first traversal.*/
cout << "printing with Breadth-first traversal" << endl;
BreadthFirstTraversal(root);
/* Prints all element at the same depth (level) */
int row = maxDepth(root);
vector<vector<int> > levVec(row+1);
BreadthFirst_LevelElement_Print(root, levVec);
for(int m = 0; m < levVec.size(); m++) {
cout << "Level at " << m << ": ";
for(int n = 0; n < levVec[m].size(); n++)
cout << (char)levVec[m][n] << " ";
cout << endl;
}
/* levelPrint()
prints nodes at the same level
This is simpler than the BreadthFirstTraversal(root) above
It takes 2D vector (elm) with the same size of level (= MaxDepth+1)
and fills elements as we traverse (preOrder) */
vector<vector<char> > elm;
int mxDepth = maxDepth(root);
elm.resize(mxDepth+1);
int level = 0;
levelPrint(root, elm, level);
cout << "levelPrint() " << endl;
for(int i = 0; i <= mxDepth; i++) {
cout << "level " << i << ": " ;
for(int j = 0; j < elm[i].size(); j++)
cout << elm[i][j] << " ";
cout << endl;
}
/* convert the tree into an array */
int treeSz = treeSize(root);
int *array = new int[treeSz];
TreeToArray(root,array);
cout << "New array: ";
for (int i = 0; i < treeSz; i++)
cout << (char)array[i] << ' ';
cout << endl;
delete [] array;
/* subtree */
Tree *root2 = newTreeNode('D');
insertTreeNode(root2,'C');
insertTreeNode(root2,'E');
cout << "1-2 subtree: " << isSubTree(root, root2) << endl;
Tree *root3 = newTreeNode('B');
insertTreeNode(root3,'A');
insertTreeNode(root3,'D');
insertTreeNode(root3,'C');
insertTreeNode(root3,'E');
cout << "1-3 subtree: " << isSubTree(root, root3) << endl;
Tree *root4 = newTreeNode('B');
insertTreeNode(root4,'D');
insertTreeNode(root4,'C');
insertTreeNode(root4,'E');
cout << "1-4 subtree: " << isSubTree(root, root4) << endl;
cout << "2-3 subtree: " << isSubTree(root2, root3) << endl;
cout << "3-2 subtree: " << isSubTree(root3, root2) << endl;
/* swap left and right */
mirror(root);
/* deleting a tree */
clear(root);
/* make a new tree with minimal depth */
Tree *newRoot = createMinimalBST(charArr,9);
return 0;
}
Bài liên quan
Code dài thế ko markdown thì mình nghĩ ngta cũng ngại giúp đấy
Cách post Code dùng Markdown trong Category Programming
Markdown trong daynhauhoc.com
Tham khảo 2 bài viết trên rồi chỉnh code lại cho gọn với dễ nhìn nha bạn
Cái này đưa rác cho người ta dọn thì có chứ đưa code cho sửa cái gì -_-
Rất đáng bị close hoặc ẩn đi.
Tại sao một CT thế này bạn ko chia thành nhiều file để dễ quản lý. Bạn gộp thế này nhìn khác j một đống rác đâu~~
vào đây đọc cho dễ nè: http://www.bogotobogo.com/cplusplus/files/BinaryTree.cpp
mất công copy rồi tự nhận là code của mình làm gì cho khổ (del thớt này đi)