This is sort of my first attempt at writing a template container class, just
wanted some feedback if everything looks kosher or if there can be any
improvements. This is a template class for a binary search tree. Note there
is a requirement for this to be a Win32/MFC "friendly" class, thus the use
of CObject and POSITION. There is also a requirement for there not to be a
separate iterator class.
template <class TYPE, class ARG_TYPE = const TYPE&> class CBinarySearchTree;
template <class TYPE, class ARG_TYPE>
class CBinarySearchTree : public CObject
{
// Constructors
public:
CBinarySearchTree();
// Attributes
public:
int GetCount() const;
POSITION GetRoot() const;
POSITION GetLeft(POSITION& pos) const;
POSITION GetRight(POSITION& pos) const;
ARG_TYPE GetElement(POSITION& pos) const;
// Operations
public:
BOOL Insert(ARG_TYPE newElement);
BOOL Remove(ARG_TYPE element);
void RemoveAll();
POSITION Find(ARG_TYPE element);
// Implementation
public:
virtual ~CBinarySearchTree();
protected:
struct _TREENODE
{
TYPE element;
_TREENODE* pLeft;
_TREENODE* pRight;
};
protected:
_TREENODE* m_pRoot;
UINT m_nCount;
protected:
BOOL Insert(ARG_TYPE newElement, _TREENODE*& pNode);
BOOL Remove(ARG_TYPE element, _TREENODE*& pNode);
LPVOID FindMin(_TREENODE* pNode);
};
////////////////////////////////////////////////////////////////////////////
/
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::CBinarySearchTree()
{
m_pRoot = NULL;
m_nCount = 0;
}
template <class TYPE, class ARG_TYPE>
CBinarySearchTree<TYPE, ARG_TYPE>::~CBinarySearchTree()
{
RemoveAll();
}
template <class TYPE, class ARG_TYPE>
int CBinarySearchTree<TYPE, ARG_TYPE>::GetCount() const
{
return m_nCount;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRoot() const
{
return (POSITION)m_pRoot;
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetLeft(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pLeft);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRight(POSITION& pos) const
{
return (POSITION)(((_TREENODE*)pos)->pRight);
}
template <class TYPE, class ARG_TYPE>
ARG_TYPE CBinarySearchTree<TYPE, ARG_TYPE>::GetElement(POSITION& pos) const
{
return ((_TREENODE*)pos)->element;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement)
{
return Insert(newElement, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element)
{
return Remove(element, m_pRoot);
}
template <class TYPE, class ARG_TYPE>
void CBinarySearchTree<TYPE, ARG_TYPE>::RemoveAll()
{
while (m_pRoot != NULL)
Remove(m_pRoot->element);
}
template <class TYPE, class ARG_TYPE>
POSITION CBinarySearchTree<TYPE, ARG_TYPE>::Find(ARG_TYPE element)
{
return NULL;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement,
_TREENODE*& pNode)
{
if (pNode != NULL)
{
if (newElement < pNode->element)
return Insert(newElement, pNode->pLeft);
if (newElement > pNode->element)
return Insert(newElement, pNode->pRight);
}
else
{
pNode = new _TREENODE;
if (!pNode)
return FALSE;
m_nCount++;
pNode->element = newElement;
pNode->pLeft = NULL;
pNode->pRight = NULL;
return TRUE;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element, _TREENODE*&
pNode)
{
_TREENODE* pTempNode = NULL;
if (!pNode)
return TRUE;
if (element < pNode->element)
{
Remove(element, pNode->pLeft);
}
else if (element > pNode->element)
{
Remove(element, pNode->pRight);
}
else if (pNode->pLeft != NULL && pNode->pRight != NULL)
{
pTempNode = (_TREENODE*)FindMin(pNode->pRight);
pNode->element = pTempNode->element;
Remove(element, pNode->pRight);
}
else
{
pTempNode = pNode;
if (m_nCount > 0)
m_nCount--;
if (!pNode->pLeft)
pNode = pNode->pRight;
else if (!pNode->pRight)
pNode = pNode->pLeft;
delete pTempNode;
}
return TRUE;
}
template <class TYPE, class ARG_TYPE>
LPVOID CBinarySearchTree<TYPE, ARG_TYPE>::FindMin(_TREENODE* pNode)
{
if (!pNode)
return NULL;
else if (!pNode->pLeft)
return (LPVOID)pNode;
return FindMin(pNode->pLeft);
}
Thanks! 6 2137
Miscellaneous comments below
"Nobody" <no****@cox.net> wrote in message
news:%ZjXb.33476$1O.26297@fed1read05... This is sort of my first attempt at writing a template container class,
just wanted some feedback if everything looks kosher or if there can be any improvements. This is a template class for a binary search tree. Note
there is a requirement for this to be a Win32/MFC "friendly" class, thus the use of CObject and POSITION. There is also a requirement for there not to be a separate iterator class.
template <class TYPE, class ARG_TYPE = const TYPE&> class
CBinarySearchTree; template <class TYPE, class ARG_TYPE> class CBinarySearchTree : public CObject { // Constructors public: CBinarySearchTree(); // Attributes public: int GetCount() const; POSITION GetRoot() const; POSITION GetLeft(POSITION& pos) const; POSITION GetRight(POSITION& pos) const; ARG_TYPE GetElement(POSITION& pos) const;
None of the above three functions modify the pos argument, therefore it
should be
ARG_TYPE GetElement(const POSITION& pos) const;
As you have coded it the following is illegal C++
mytree.GetElement(mytree.GetRoot())
which is a bit of a restriction. As it happens MSVC++ does not enforce this,
but that is MSVC++'s problem, there's still no excuse for using non-const
references where const references are correct.
Also can't you make GetLeft, GetRight and GetElement static? It would make
them very slightly more useable (in the absense of a seperate iterator
class).
// Operations public: BOOL Insert(ARG_TYPE newElement); BOOL Remove(ARG_TYPE element);
bool not BOOL. bool is standard C++, BOOL is not. Try to avoid non-standard
code when there is no good reason for it. (Being more like MFC is not a good
enough reason).
void RemoveAll(); POSITION Find(ARG_TYPE element); // Implementation public: virtual ~CBinarySearchTree(); protected: struct _TREENODE
Names with an underscore followed by a capital letter are reserved for
compiler and standard library uses. So _TREENODE is not legal.
{ TYPE element; _TREENODE* pLeft; _TREENODE* pRight; }; protected: _TREENODE* m_pRoot; UINT m_nCount;
Ditto unsigned not UINT. Actually probably should be size_t (64 bit
computing is round the corner, size_t will be a 64 bit type when it arrives)
protected: BOOL Insert(ARG_TYPE newElement, _TREENODE*& pNode); BOOL Remove(ARG_TYPE element, _TREENODE*& pNode); LPVOID FindMin(_TREENODE* pNode);
Ditto, void* not LPVOID.
};
No copy constructor or assignment operator. You can implement these easily
enough using the member functions you have already defined, so why not do
it?
//////////////////////////////////////////////////////////////////////////// /
template <class TYPE, class ARG_TYPE> CBinarySearchTree<TYPE, ARG_TYPE>::CBinarySearchTree() { m_pRoot = NULL; m_nCount = 0; }
template <class TYPE, class ARG_TYPE> CBinarySearchTree<TYPE, ARG_TYPE>::~CBinarySearchTree() { RemoveAll(); }
template <class TYPE, class ARG_TYPE> int CBinarySearchTree<TYPE, ARG_TYPE>::GetCount() const { return m_nCount; }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRoot() const { return (POSITION)m_pRoot; }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetLeft(POSITION& pos) const { return (POSITION)(((_TREENODE*)pos)->pLeft); }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRight(POSITION& pos) const { return (POSITION)(((_TREENODE*)pos)->pRight); }
template <class TYPE, class ARG_TYPE> ARG_TYPE CBinarySearchTree<TYPE, ARG_TYPE>::GetElement(POSITION& pos)
const { return ((_TREENODE*)pos)->element; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement) { return Insert(newElement, m_pRoot); }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element) { return Remove(element, m_pRoot); }
template <class TYPE, class ARG_TYPE> void CBinarySearchTree<TYPE, ARG_TYPE>::RemoveAll() { while (m_pRoot != NULL) Remove(m_pRoot->element); }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::Find(ARG_TYPE element) {
Huh?
return NULL; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement, _TREENODE*& pNode)
I'd like to see this function return true if an element was inserted and
false if you attempt to insert a duplicate element, and a exception thrown
for the out of memory error.
This code is not exception safe, but I guess you aren't too worried about
that.
{ if (pNode != NULL) { if (newElement < pNode->element) return Insert(newElement, pNode->pLeft);
if (newElement > pNode->element) return Insert(newElement, pNode->pRight); } else { pNode = new _TREENODE;
if (!pNode) return FALSE;
More MCVC++ specific code. new does return NULL on memory exhaustion in
standard C++, it throws an exception instead. m_nCount++;
pNode->element = newElement; pNode->pLeft = NULL; pNode->pRight = NULL;
I think the above is better written like this
_TREENODE* tmp;
tmp = new _TREENODE(newElement);
if (tmp == 0) // MSVC++ specific code, new can return NULL in MSVC++
throw std::bad_alloc(); // do the right thing on memory
exhaustion
pNode = tmp;
++m_nCount;
You'll have to add the constructor for _TREENODE.
This code has two points, it does the correct thing on memory exhaustion,
and it is exception safe, i.e. if either you run out of memory, or if
copying the newElement throws an exception then your tree is left unchanged,
that is not the case with your current code. return TRUE; }
return TRUE; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element,
_TREENODE*& pNode) { _TREENODE* pTempNode = NULL;
if (!pNode) return TRUE;
if (element < pNode->element) { Remove(element, pNode->pLeft); } else if (element > pNode->element) { Remove(element, pNode->pRight); } else if (pNode->pLeft != NULL && pNode->pRight != NULL) { pTempNode = (_TREENODE*)FindMin(pNode->pRight); pNode->element = pTempNode->element; Remove(element, pNode->pRight); } else { pTempNode = pNode;
if (m_nCount > 0)
m_nCount--;
if (!pNode->pLeft) pNode = pNode->pRight; else if (!pNode->pRight) pNode = pNode->pLeft;
delete pTempNode; }
return TRUE; }
template <class TYPE, class ARG_TYPE> LPVOID CBinarySearchTree<TYPE, ARG_TYPE>::FindMin(_TREENODE* pNode) { if (!pNode) return NULL; else if (!pNode->pLeft) return (LPVOID)pNode;
return FindMin(pNode->pLeft); }
Thanks!
john
> No copy constructor or assignment operator. You can implement these easily enough using the member functions you have already defined, so why not do it?
Actually scratch that. A copy ctor written that way would not be efficient.
You should use a straightforward recursive tree copy instead.
john
Thanks for the feedback John. Some good technical points here that I will
modify my code for and some style issues that are "to each his own" :).
Ooops, in the code posted, the Find function was not implemented.
Why make the GetElement, GetLeft and GetRight static? I understand they
operate on the node struct and not the tree itself, but does it add anything
to be static?
If those methods were static, wouldn't I have to call them with some ugly
code like:
CBinarySearchTree<int>::GetLeft(pos);
or something of that nature? vs.
tree.GetLeft(pos);
I have always followed the belief of not making class functions or members
static. If a member function is static, it probably shouldn't be a member
function.
Yes, I do need to implement a copy constructor as well.
Again, thanks for the feedback, much appreciated.
"John Harrison" <jo*************@hotmail.com> wrote in message
news:c0*************@ID-196037.news.uni-berlin.de... Miscellaneous comments below
"Nobody" <no****@cox.net> wrote in message news:%ZjXb.33476$1O.26297@fed1read05... This is sort of my first attempt at writing a template container class, just wanted some feedback if everything looks kosher or if there can be any improvements. This is a template class for a binary search tree. Note there is a requirement for this to be a Win32/MFC "friendly" class, thus the
use of CObject and POSITION. There is also a requirement for there not to be
a separate iterator class.
template <class TYPE, class ARG_TYPE = const TYPE&> class CBinarySearchTree; template <class TYPE, class ARG_TYPE> class CBinarySearchTree : public CObject { // Constructors public: CBinarySearchTree(); // Attributes public: int GetCount() const; POSITION GetRoot() const; POSITION GetLeft(POSITION& pos) const; POSITION GetRight(POSITION& pos) const; ARG_TYPE GetElement(POSITION& pos) const;
None of the above three functions modify the pos argument, therefore it should be
ARG_TYPE GetElement(const POSITION& pos) const;
As you have coded it the following is illegal C++
mytree.GetElement(mytree.GetRoot())
which is a bit of a restriction. As it happens MSVC++ does not enforce
this, but that is MSVC++'s problem, there's still no excuse for using non-const references where const references are correct.
Also can't you make GetLeft, GetRight and GetElement static? It would make them very slightly more useable (in the absense of a seperate iterator class).
// Operations public: BOOL Insert(ARG_TYPE newElement); BOOL Remove(ARG_TYPE element); bool not BOOL. bool is standard C++, BOOL is not. Try to avoid
non-standard code when there is no good reason for it. (Being more like MFC is not a
good enough reason).
void RemoveAll(); POSITION Find(ARG_TYPE element); // Implementation public: virtual ~CBinarySearchTree(); protected: struct _TREENODE Names with an underscore followed by a capital letter are reserved for compiler and standard library uses. So _TREENODE is not legal.
{ TYPE element; _TREENODE* pLeft; _TREENODE* pRight; }; protected: _TREENODE* m_pRoot; UINT m_nCount;
Ditto unsigned not UINT. Actually probably should be size_t (64 bit computing is round the corner, size_t will be a 64 bit type when it
arrives) protected: BOOL Insert(ARG_TYPE newElement, _TREENODE*& pNode); BOOL Remove(ARG_TYPE element, _TREENODE*& pNode); LPVOID FindMin(_TREENODE* pNode); Ditto, void* not LPVOID.
};
No copy constructor or assignment operator. You can implement these easily enough using the member functions you have already defined, so why not do it?
//////////////////////////////////////////////////////////////////////////// /
template <class TYPE, class ARG_TYPE> CBinarySearchTree<TYPE, ARG_TYPE>::CBinarySearchTree() { m_pRoot = NULL; m_nCount = 0; }
template <class TYPE, class ARG_TYPE> CBinarySearchTree<TYPE, ARG_TYPE>::~CBinarySearchTree() { RemoveAll(); }
template <class TYPE, class ARG_TYPE> int CBinarySearchTree<TYPE, ARG_TYPE>::GetCount() const { return m_nCount; }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRoot() const { return (POSITION)m_pRoot; }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetLeft(POSITION& pos) const { return (POSITION)(((_TREENODE*)pos)->pLeft); }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::GetRight(POSITION& pos)
const { return (POSITION)(((_TREENODE*)pos)->pRight); }
template <class TYPE, class ARG_TYPE> ARG_TYPE CBinarySearchTree<TYPE, ARG_TYPE>::GetElement(POSITION& pos) const { return ((_TREENODE*)pos)->element; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement) { return Insert(newElement, m_pRoot); }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element) { return Remove(element, m_pRoot); }
template <class TYPE, class ARG_TYPE> void CBinarySearchTree<TYPE, ARG_TYPE>::RemoveAll() { while (m_pRoot != NULL) Remove(m_pRoot->element); }
template <class TYPE, class ARG_TYPE> POSITION CBinarySearchTree<TYPE, ARG_TYPE>::Find(ARG_TYPE element) {
Huh?
return NULL; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Insert(ARG_TYPE newElement, _TREENODE*& pNode)
I'd like to see this function return true if an element was inserted and false if you attempt to insert a duplicate element, and a exception thrown for the out of memory error.
This code is not exception safe, but I guess you aren't too worried about that.
{ if (pNode != NULL) { if (newElement < pNode->element) return Insert(newElement, pNode->pLeft);
if (newElement > pNode->element) return Insert(newElement, pNode->pRight); } else { pNode = new _TREENODE;
if (!pNode) return FALSE;
More MCVC++ specific code. new does return NULL on memory exhaustion in standard C++, it throws an exception instead.
m_nCount++;
pNode->element = newElement; pNode->pLeft = NULL; pNode->pRight = NULL;
I think the above is better written like this
_TREENODE* tmp; tmp = new _TREENODE(newElement); if (tmp == 0) // MSVC++ specific code, new can return NULL in
MSVC++ throw std::bad_alloc(); // do the right thing on memory exhaustion pNode = tmp; ++m_nCount;
You'll have to add the constructor for _TREENODE.
This code has two points, it does the correct thing on memory exhaustion, and it is exception safe, i.e. if either you run out of memory, or if copying the newElement throws an exception then your tree is left
unchanged, that is not the case with your current code.
return TRUE; }
return TRUE; }
template <class TYPE, class ARG_TYPE> BOOL CBinarySearchTree<TYPE, ARG_TYPE>::Remove(ARG_TYPE element,
_TREENODE*& pNode) { _TREENODE* pTempNode = NULL;
if (!pNode) return TRUE;
if (element < pNode->element) { Remove(element, pNode->pLeft); } else if (element > pNode->element) { Remove(element, pNode->pRight); } else if (pNode->pLeft != NULL && pNode->pRight != NULL) { pTempNode = (_TREENODE*)FindMin(pNode->pRight); pNode->element = pTempNode->element; Remove(element, pNode->pRight); } else { pTempNode = pNode;
if (m_nCount > 0)
m_nCount--;
if (!pNode->pLeft) pNode = pNode->pRight; else if (!pNode->pRight) pNode = pNode->pLeft;
delete pTempNode; }
return TRUE; }
template <class TYPE, class ARG_TYPE> LPVOID CBinarySearchTree<TYPE, ARG_TYPE>::FindMin(_TREENODE* pNode) { if (!pNode) return NULL; else if (!pNode->pLeft) return (LPVOID)pNode;
return FindMin(pNode->pLeft); }
Thanks!
john
"Nobody" <no****@cox.net> wrote in message
news:0hlXb.33481$1O.1549@fed1read05... Thanks for the feedback John. Some good technical points here that I will modify my code for and some style issues that are "to each his own" :).
Ooops, in the code posted, the Find function was not implemented.
Why make the GetElement, GetLeft and GetRight static? I understand they operate on the node struct and not the tree itself, but does it add
anything to be static?
If those methods were static, wouldn't I have to call them with some ugly code like:
CBinarySearchTree<int>::GetLeft(pos);
or something of that nature? vs.
tree.GetLeft(pos);
No, you can use EITHER syntax if the function is static. The point of making
them static is that you can do node iteration without having the original
tree.
I have always followed the belief of not making class functions or members static. If a member function is static, it probably shouldn't be a member function.
Fair enough, although I wouldn't be as categorical as you are being. But in
this case these three functions should be part of a seperate iterator class,
but you've already ruled that out, so I thought making them static is the
next best thing.
It's going to get very tedious when writing functions that use GetLeft,
GetRight and GetElement to always have to pass the tree itself to that
function as well. Yes, I do need to implement a copy constructor as well.
Again, thanks for the feedback, much appreciated.
john
John Harrison wrote: Miscellaneous comments below
"Nobody" <no****@cox.net> wrote in message news:%ZjXb.33476$1O.26297@fed1read05...
{ TYPE element; _TREENODE* pLeft; _TREENODE* pRight; }; protected: _TREENODE* m_pRoot; UINT m_nCount;
Ditto unsigned not UINT. Actually probably should be size_t (64 bit computing is round the corner, size_t will be a 64 bit type when it arrives)
I noticed the following comment in gc.h from Hans Boehm's garbage
collector: "[size_t] and [ptr_diff_t] appear to have incorrect
definitions on many systems. Notably 'typedef int size_t' seems to be
both frequent and WRONG." Comments?
"Jon Willeke" <j.***********@verizon.dot.net> wrote in message
news:qN*****************@nwrdny02.gnilink.net... John Harrison wrote: Miscellaneous comments below
"Nobody" <no****@cox.net> wrote in message news:%ZjXb.33476$1O.26297@fed1read05...
{ TYPE element; _TREENODE* pLeft; _TREENODE* pRight; }; protected: _TREENODE* m_pRoot; UINT m_nCount; Ditto unsigned not UINT. Actually probably should be size_t (64 bit computing is round the corner, size_t will be a 64 bit type when it
arrives) I noticed the following comment in gc.h from Hans Boehm's garbage collector: "[size_t] and [ptr_diff_t] appear to have incorrect definitions on many systems. Notably 'typedef int size_t' seems to be both frequent and WRONG." Comments?
I believe the standard requires size_t to be an unsigned integral type. Hans
Boehm's garbage collector is very old. I doubt that many compilers get
size_t wrong nowadays.
john This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Jerry Khoo |
last post by:
hello, everybody, i am kinda new here, nice to meet u all. Now, i am
> cs students and are now facing difficult problems in understanding
> what a binary tree is, how it works, and the algorithm...
|
by: Jerry Khoo |
last post by:
hello, everybody, i am kinda new here, nice to meet u all. Now, i am
cs students and are now facing difficult problems in understanding
what a binary tree is, how it works, and the algorithm to...
|
by: Reed |
last post by:
Can someone stear me in the right direction to convert a binary tree
from a Linked List to a Dynamic Array... Dynamic arrays aren't
something im strong with.
//********bintree.h********
#ifndef...
|
by: mathon |
last post by:
Hello,
im currently implementing a binary search tree means, that a greater
number than root will be added as right child and a less number as left
child. My insert function looks currently like...
|
by: hn.ft.pris |
last post by:
I have the following code:
Tree.h defines a simple binary search tree node structure
########## FILE Tree.h ################
#ifndef TREE_H
#define TREE_H
//using namespace std;
template...
|
by: whitehatmiracle |
last post by:
Hello
I have written a program for a binary tree. On compiling one has to
first chose option 1 and then delete or search. Im having some trouble
with the balancing function. It seems to be going...
|
by: n.noumia |
last post by:
- with 10 nodes, give one example of an unbalanced binary tree and
one example of a balanced binary tree
- what is the advantage of having a balanced binary tree over an
unbalanced tree?
- number...
|
by: Defected |
last post by:
Hi,
How i can create a Binary Search Tree with a class ?
thanks
|
by: APEJMAN |
last post by:
would you please help me?
I wrote 3 separate line of code for printing my binary tree, and now I am trying to print the level-order traversal of the tree, where the nodes at each level of the tree...
|
by: DolphinDB |
last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation.
Take...
|
by: DolphinDB |
last post by:
Tired of spending countless mintues downsampling your data? Look no further!
In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: jfyes |
last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
|
by: ArrayDB |
last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
by: af34tf |
last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
| |