【发布时间】:2017-04-21 16:43:20
【问题描述】:
我正在研究 AVL 树排序算法,我想我终于弄明白了,感谢大家的帮助,直到我意识到它的运行时间比插入排序的运行时间要长得多,这不应该是正确的。我正在使用随机生成的数字的未排序数组(或更确切地说是向量)。我将在下面提供一些统计数据和代码。
AVL
for (std::vector<int>::const_iterator i = numbers.begin(); i != numbers.begin()+30000; ++i)
{
root = insert(root, numbers[x]);
cout << "Height: " << height(root);
x++;
track++;
if( (track % 10000) == 0)
{
cout << track << " iterations" << endl;
time_t now = time(0);
cout << now - begin << " seconds" << endl;
}
}
N = 30,000
身高 = 17
执行的迭代次数 = ~1,730,000
排序运行时间 = 38 秒
插入排序
for (int i = 0; i < 30000; i++)
{
first++;
cout << first << " first level iterations" << endl;
time_t now = time(0);
cout << now - begin << " seconds" << endl;
int tmp = dataSet[i];
int j;
for (j = i; i > 0 && tmp < dataSet[j - 1]; j--)
{
dataSet[j] = dataSet[j - 1];
}
dataSet[j] = tmp;
}
}
N = 30,000
迭代次数 = 30,000
排序运行时间 = 4 秒
这不可能是正确的,所以我希望也许你们都可以帮助弄清楚发生了什么?据我所知,我的所有代码都已正确实现,但我仍将包括下面的相关部分,以防我遗漏了什么。
源代码
node* newNode(int element) // helper function to return a new node with empty subtrees
{
node* newPtr = new node;
newPtr->data = element;
newPtr->leftChild = NULL;
newPtr->rightChild = NULL;
newPtr->height = 1;
return newPtr;
}
node* rightRotate(node* p) // function to right rotate a tree rooted at p
{
node* child = p->leftChild;
node* grandChild = child->rightChild;
// perform the rotation
child->rightChild = p;
p->leftChild = grandChild;
// update the height for the nodes
p->height = max(height(p->leftChild), height(p->rightChild)) + 1;
child->height = max(height(child->leftChild), height(child->rightChild)) + 1;
// return new root
return child;
}
node* leftRotate(node* p) // function to left rotate a tree rooted at p
{
node* child = p->rightChild;
node* grandChild = child->leftChild;
// perform the rotation
child->leftChild = p;
p->rightChild = grandChild;
// update heights
p->height = max(height(p->leftChild), height(p->rightChild)) + 1;
// return new root
return child;
}
int getBalance(node *p)
{
if(p == NULL)
return 0;
else
return height(p->leftChild) - height(p->rightChild);
}
// recursive version of BST insert to insert the element in a sub tree rooted with root
// which returns new root of subtree
node* insert(node*& n, int element)
{
// perform the normal BST insertion
if(n == NULL) // if the tree is empty
return(newNode(element));
if(element< n->data)
{
n->leftChild = insert(n->leftChild, element);
}
else
{
n->rightChild = insert(n->rightChild, element);
}
// update the height for this node
n->height = 1 + max(height(n->leftChild), height(n->rightChild));
// get the balance factor to see if the tree is unbalanced
int balance = getBalance(n);
// the tree is unbalanced, there are 4 different types of rotation to make
// Single Right Rotation (Left Left Case)
if(balance > 1 && element < n->leftChild->data)
{
return rightRotate(n);
}
// Single Left Rotation (Right Right Case)
if(balance < -1 && element > n->rightChild->data)
{
return leftRotate(n);
}
// Left Right Rotation
if(balance > 1 && element > n->leftChild->data)
{
n->leftChild = leftRotate(n->leftChild);
return rightRotate(n);
}
// Right Left Rotation
if(balance < -1 && element < n->rightChild->data)
{
n->rightChild = rightRotate(n->rightChild);
return leftRotate(n);
}
// cout << "Height: " << n->height << endl;
// return the unmodified root pointer in the case that the tree does not become unbalanced
return n;
}
【问题讨论】:
-
由于插入排序非常简单,而 AVL 树则不然,即使在尝试任何事情之前,也有理由怀疑 AVL 排序具有更高的常数因子。
-
@harold top of that 他在循环中间调用 height(root),这增加了更多的常数因子。
-
我不确定我是否理解您的意思。你能详细说明一下吗?
标签: c++ algorithm sorting binary-search-tree avl-tree