1、findkth
代码:
//#ifndef BINARY_SEARCH_TREE_H
//#define BINARY_SEARCH_TREE_H
//#include "dsexceptions.h"
#include <algorithm>
#include<iostream>
using namespace std;
// BinarySearchTree class
//
// CONSTRUCTION: zero parameter
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x
// bool contains( x ) --> Return true if x is present
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order
// ******************ERRORS********************************
// Throws UnderflowException as warranted
template <typename Comparable>
class BinarySearchTree
{
public:
BinarySearchTree( ) : root{ nullptr }
{
}
/**
* Copy constructor
*/
BinarySearchTree( const BinarySearchTree & rhs ) : root{ nullptr }
{
root = clone( rhs.root );
}
/**
* Move constructor
*/
BinarySearchTree( BinarySearchTree && rhs ) : root{ rhs.root }
{
rhs.root = nullptr;
}
/**
* Destructor for the tree
*/
~BinarySearchTree( )
{
makeEmpty( );
}
/**
* Copy assignment
*/
BinarySearchTree & operator=( const BinarySearchTree & rhs )
{
BinarySearchTree copy = rhs;
std::swap( *this, copy );
return *this;
}
/**
* Move assignment
*/
BinarySearchTree & operator=( BinarySearchTree && rhs )
{
std::swap( root, rhs.root );
return *this;
}
/**
* Find the smallest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable & findMin( ) const
{
if( isEmpty( ) )
//throw UnderflowException{ };
cout<<"error"<<endl;
return ;
return findMin( root )->element;
}
/**
* Find the largest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable & findMax( ) const
{
if( isEmpty( ) )
//throw UnderflowException{ };
cout<<"error"<<endl;
return ;
return findMax( root )->element;
}
/**
* Returns true if x is found in the tree.
*/
bool contains( const Comparable & x ) const
{
return contains( x, root );
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
bool isEmpty( ) const
{
return root == nullptr;
}
/**
* Print the tree contents in sorted order.
*/
void printTree( ostream & out = cout ) const
{
if( isEmpty( ) )
out << "Empty tree" << endl;
else
printTree( root, out );
}
/**
* Make the tree logically empty.
*/
void makeEmpty( )
{
makeEmpty( root );
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert( const Comparable & x )
{
insert( x, root );
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert( Comparable && x )
{
insert( std::move( x ), root );
}
/**
* Remove x from the tree. Nothing is done if x is not found.
*/
void remove( const Comparable & x )
{
remove( x, root );
}
Comparable kthSmallest(int k)
{
return kthSmallestDFS(root, k);
}
private:
struct BinaryNode
{
Comparable element;
BinaryNode *left;
BinaryNode *right;
BinaryNode( const Comparable & theElement, BinaryNode *lt, BinaryNode *rt )
: element{ theElement }, left{ lt }, right{ rt } { }
BinaryNode( Comparable && theElement, BinaryNode *lt, BinaryNode *rt )
: element{ std::move( theElement ) }, left{ lt }, right{ rt } { }
};
BinaryNode *root;
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void insert( const Comparable & x, BinaryNode * & t )
{
if( t == nullptr )
t = new BinaryNode{ x, nullptr, nullptr };
else if( x < t->element )
insert( x, t->left );
else if( t->element < x )
insert( x, t->right );
else
; // Duplicate; do nothing
}
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void insert( Comparable && x, BinaryNode * & t )
{
if( t == nullptr )
t = new BinaryNode{ std::move( x ), nullptr, nullptr };
else if( x < t->element )
insert( std::move( x ), t->left );
else if( t->element < x )
insert( std::move( x ), t->right );
else
; // Duplicate; do nothing
}
/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void remove( const Comparable & x, BinaryNode * & t )
{
if( t == nullptr )
return; // Item not found; do nothing
if( x < t->element )
remove( x, t->left );
else if( t->element < x )
remove( x, t->right );
else if( t->left != nullptr && t->right != nullptr ) // Two children
{
t->element = findMin( t->right )->element;
remove( t->element, t->right );
}
else
{
BinaryNode *oldNode = t;
t = ( t->left != nullptr ) ? t->left : t->right;
delete oldNode;
}
}
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
BinaryNode * findMin( BinaryNode *t ) const
{
if( t == nullptr )
return nullptr;
if( t->left == nullptr )
return t;
return findMin( t->left );
}
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
BinaryNode * findMax( BinaryNode *t ) const
{
if( t != nullptr )
while( t->right != nullptr )
t = t->right;
return t;
}
/**
* Internal method to test if an item is in a subtree.
* x is item to search for.
* t is the node that roots the subtree.
*/
bool contains( const Comparable & x, BinaryNode *t ) const
{
if( t == nullptr )
return false;
else if( x < t->element )
return contains( x, t->left );
else if( t->element < x )
return contains( x, t->right );
else
return true; // Match
}
/****** NONRECURSIVE VERSION*************************
bool contains( const Comparable & x, BinaryNode *t ) const
{
while( t != nullptr )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return true; // Match
return false; // No match
}
*****************************************************/
/**
* Internal method to make subtree empty.
*/
void makeEmpty( BinaryNode * & t )
{
if( t != nullptr )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = nullptr;
}
/**
* Internal method to print a subtree rooted at t in sorted order.
*/
void printTree( BinaryNode *t, ostream & out ) const
{
if( t != nullptr )
{
printTree( t->left, out );
out << t->element << endl;
printTree( t->right, out );
}
}
/**
* Internal method to clone subtree.
*/
BinaryNode * clone( BinaryNode *t ) const
{
if( t == nullptr )
return nullptr;
else
return new BinaryNode{ t->element, clone( t->left ), clone( t->right ) };
}
Comparable kthSmallest(BinaryNode* root, int k) {
return kthSmallestDFS(root, k);
}
Comparable kthSmallestDFS(BinaryNode *root, int &k) {
if (!root) return -1;
int val = kthSmallestDFS(root->left, k);
if (!k) return val;
if (!--k) return root->element;
return kthSmallestDFS(root->right, k);
}
};
/*findkth
因为左节点小于根节点小于右节点,二叉搜索树的一个特性就是中序遍历的结果
就是树内节点从小到大顺序输出的结果。这里采用迭代形式,我们就可以在找到
第k小节点时马上退出。递归这样的时间复杂度是O(logN)。*/
int main()
{
BinarySearchTree <char> bt;
char a;
cout<<"请输入二叉搜索树的全部元素:"<<endl;
while(cin>>a)
{
if(a=='#')break;
bt.insert(a);
}
bt.printTree();
int k;
cin>>k;
cout<<"第M小的数是:"<<bt.kthSmallest(k)<<endl;
return 0;
}
//#endif
2、建立AVI树
3、实现高效旋转
代码:
//#ifndef AVL_TREE_H
//#define AVL_TREE_H
//#include "dsexceptions.h"
#include <algorithm>
#include <iostream>
using namespace std;
// AvlTree class
//
// CONSTRUCTION: zero parameter
//
// ******************PUBLIC OPERATIONS*********************
// void insert( x ) --> Insert x
// void remove( x ) --> Remove x (unimplemented)
// bool contains( x ) --> Return true if x is present
// Comparable findMin( ) --> Return smallest item
// Comparable findMax( ) --> Return largest item
// boolean isEmpty( ) --> Return true if empty; else false
// void makeEmpty( ) --> Remove all items
// void printTree( ) --> Print tree in sorted order
// ******************ERRORS********************************
// Throws UnderflowException as warranted
template <typename Comparable>
class AvlTree
{
public:
AvlTree( ) : root{ nullptr }
{ }
AvlTree( const AvlTree & rhs ) : root{ nullptr }
{
root = clone( rhs.root );
}
AvlTree( AvlTree && rhs ) : root{ rhs.root }
{
rhs.root = nullptr;
}
~AvlTree( )
{
makeEmpty( );
}
/**
* Deep copy.
*/
AvlTree & operator=( const AvlTree & rhs )
{
AvlTree copy = rhs;
std::swap( *this, copy );
return *this;
}
/**
* Move.
*/
AvlTree & operator=( AvlTree && rhs )
{
std::swap( root, rhs.root );
return *this;
}
/**
* Find the smallest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable & findMin( ) const
{
if( isEmpty( ) )
return ;//throw UnderflowException{ };
return findMin( root )->element;
}
/**
* Find the largest item in the tree.
* Throw UnderflowException if empty.
*/
const Comparable & findMax( ) const
{
if( isEmpty( ) )
return ;//throw UnderflowException{ };
return findMax( root )->element;
}
/**
* Returns true if x is found in the tree.
*/
bool contains( const Comparable & x ) const
{
return contains( x, root );
}
/**
* Test if the tree is logically empty.
* Return true if empty, false otherwise.
*/
bool isEmpty( ) const
{
return root == nullptr;
}
/**
* Print the tree contents in sorted order.
*/
void printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}
/**
* Make the tree logically empty.
*/
void makeEmpty( )
{
makeEmpty( root );
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert( const Comparable & x )
{
insert( x, root );
}
/**
* Insert x into the tree; duplicates are ignored.
*/
void insert( Comparable && x )
{
insert( std::move( x ), root );
}
/**
* Remove x from the tree. Nothing is done if x is not found.
*/
void remove( const Comparable & x )
{
remove( x, root );
}
private:
struct AvlNode
{
Comparable element;
AvlNode *left;
AvlNode *right;
int height;
AvlNode( const Comparable & ele, AvlNode *lt, AvlNode *rt, int h = 0 )
: element{ ele }, left{ lt }, right{ rt }, height{ h } { }
AvlNode( Comparable && ele, AvlNode *lt, AvlNode *rt, int h = 0 )
: element{ std::move( ele ) }, left{ lt }, right{ rt }, height{ h } { }
};
AvlNode *root;
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void insert( const Comparable & x, AvlNode * & t )
{
if( t == nullptr )
t = new AvlNode{ x, nullptr, nullptr };
else if( x < t->element )
insert( x, t->left );
else if( t->element < x )
insert( x, t->right );
balance( t );
}
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void insert( Comparable && x, AvlNode * & t )
{
if( t == nullptr )
t = new AvlNode{ std::move( x ), nullptr, nullptr };
else if( x < t->element )
insert( std::move( x ), t->left );
else if( t->element < x )
insert( std::move( x ), t->right );
balance( t );
}
/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the subtree.
* Set the new root of the subtree.
*/
void remove( const Comparable & x, AvlNode * & t )
{
if( t == nullptr )
return; // Item not found; do nothing
if( x < t->element )
remove( x, t->left );
else if( t->element < x )
remove( x, t->right );
else if( t->left != nullptr && t->right != nullptr ) // Two children
{
t->element = findMin( t->right )->element;
remove( t->element, t->right );
}
else
{
AvlNode *oldNode = t;
t = ( t->left != nullptr ) ? t->left : t->right;
delete oldNode;
}
balance( t );
}
static const int ALLOWED_IMBALANCE = 1;
// Assume t is balanced or within one of being balanced
void balance( AvlNode * & t )
{
if( t == nullptr )
return;
if( height( t->left ) - height( t->right ) > ALLOWED_IMBALANCE )
if( height( t->left->left ) >= height( t->left->right ) )
rotateWithLeftChild( t );
else
doubleWithLeftChildPlus( t );
else
if( height( t->right ) - height( t->left ) > ALLOWED_IMBALANCE )
if( height( t->right->right ) >= height( t->right->left ) )
rotateWithRightChild( t );
else
doubleWithRightChildPlus( t );
t->height = max( height( t->left ), height( t->right ) ) + 1;
}
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
AvlNode * findMin( AvlNode *t ) const
{
if( t == nullptr )
return nullptr;
if( t->left == nullptr )
return t;
return findMin( t->left );
}
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
AvlNode * findMax( AvlNode *t ) const
{
if( t != nullptr )
while( t->right != nullptr )
t = t->right;
return t;
}
/**
* Internal method to test if an item is in a subtree.
* x is item to search for.
* t is the node that roots the tree.
*/
bool contains( const Comparable & x, AvlNode *t ) const
{
if( t == nullptr )
return false;
else if( x < t->element )
return contains( x, t->left );
else if( t->element < x )
return contains( x, t->right );
else
return true; // Match
}
/****** NONRECURSIVE VERSION*************************
bool contains( const Comparable & x, AvlNode *t ) const
{
while( t != nullptr )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return true; // Match
return false; // No match
}
*****************************************************/
/**
* Internal method to make subtree empty.
*/
void makeEmpty( AvlNode * & t )
{
if( t != nullptr )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = nullptr;
}
/**
* Internal method to print a subtree rooted at t in sorted order.
*/
void printTree( AvlNode *t ) const
{
if( t != nullptr )
{
printTree( t->left );
cout << t->element << endl;
printTree( t->right );
}
}
/**
* Internal method to clone subtree.
*/
AvlNode * clone( AvlNode *t ) const
{
if( t == nullptr )
return nullptr;
else
return new AvlNode{ t->element, clone( t->left ), clone( t->right ), t->height };
}
// Avl manipulations
/**
* Return the height of node t or -1 if nullptr.
*/
int height( AvlNode *t ) const
{
return t == nullptr ? -1 : t->height;
}
int max( int lhs, int rhs ) const
{
return lhs > rhs ? lhs : rhs;
}
/**
* Rotate binary tree node with left child.
* For AVL trees, this is a single rotation for case 1.
* Update heights, then set new root.
*/
void rotateWithLeftChild( AvlNode * & k2 )
{
AvlNode *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2->height = max( height( k2->left ), height( k2->right ) ) + 1;
k1->height = max( height( k1->left ), k2->height ) + 1;
k2 = k1;
}
/**
* Rotate binary tree node with right child.
* For AVL trees, this is a single rotation for case 4.
* Update heights, then set new root.
*/
void rotateWithRightChild( AvlNode * & k1 )
{
AvlNode *k2 = k1->right;
k1->right = k2->left;
k2->left = k1;
k1->height = max( height( k1->left ), height( k1->right ) ) + 1;
k2->height = max( height( k2->right ), k1->height ) + 1;
k1 = k2;
}
/**
* Double rotate binary tree node: first left child.
* with its right child; then node k3 with new left child.
* For AVL trees, this is a double rotation for case 2.
* Update heights, then set new root.
*/
void doubleWithLeftChildPlus(AvlNode * & k3)
{
AvlNode * k2 = k3->left->right;
AvlNode * k1 = k3->left;
k1->right = k2->left;
k3->left = k2->right;
k2->left = k1;
k2->right = k3;
k3->height = max(height(k3->left), height(k3->right))+1;
k1->height = max(height(k1->left), height(k1->right))+1;
k2->height = max(k1->height, k3->height) + 1;
k3 = k2;
}
/**
* Double rotate binary tree node: first right child.
* with its left child; then node k1 with new right child.
* For AVL trees, this is a double rotation for case 3.
* Update heights, then set new root.
*/
void doubleWithRightChildPlus(AvlNode * & k3)
{
AvlNode * k2 = k3->right->left;
AvlNode * k1 = k3->right;
k1->left = k2->right;
k3->right = k2->left;
k2->right = k1;
k2->left = k3;
k3->height = max(height(k3->left), height(k3->right)) + 1;
k1->height = max(height(k1->left), height(k1->right)) + 1;
k2->height = max(k1->height, k3->height) + 1;
k3 = k2;
}
};
int main()
{
AvlTree<int> at;
int a;
cout<<"请输入数据(以'#'结束):"<<endl;
while(cin>>a)
{
at.insert(a);
}
at.printTree();
return 0;
}
//#endif