美文网首页
堆/二分搜索树/图

堆/二分搜索树/图

作者: 什锦甜 | 来源:发表于2018-03-19 13:23 被阅读6次

    最大堆

    template<typename Item>
    class MaxHeap{
    
    private:
        Item *data;
        int count;
        int capacity;
    
        void shiftUp(int k){
            while( k > 1 && data[k/2] < data[k] ){
                swap( data[k/2], data[k] );
                k /= 2;
            }
        }
    
        void shiftDown(int k){
            while( 2*k <= count ){
                int j = 2*k;
                if( j+1 <= count && data[j+1] > data[j] ) j ++;
                if( data[k] >= data[j] ) break;
                swap( data[k] , data[j] );
                k = j;
            }
        }
    
    public:
    
        MaxHeap(int capacity){
            data = new Item[capacity+1];
            count = 0;
            this->capacity = capacity;
        }
    
        MaxHeap(Item arr[], int n){
            data = new Item[n+1];
            capacity = n;
    
            for( int i = 0 ; i < n ; i ++ )
                data[i+1] = arr[i];
            count = n;
    
            for( int i = count/2 ; i >= 1 ; i -- )
                shiftDown(i);
        }
    
        ~MaxHeap(){
            delete[] data;
        }
    
        int size(){
            return count;
        }
    
        bool isEmpty(){
            return count == 0;
        }
    
        void insert(Item item){
            assert( count + 1 <= capacity );
            data[count+1] = item;
            shiftUp(count+1);
            count ++;
        }
    
        Item extractMax(){
            assert( count > 0 );
            Item ret = data[1];
            swap( data[1] , data[count] );
            count --;
            shiftDown(1);
            return ret;
        }
    
        Item getMax(){
            assert( count > 0 );
            return data[1];
        }
    };
    
    

    heap sort

    template<typename T>
    void heapSort2(T arr[], int n){
    
        MaxHeap<T> maxheap = MaxHeap<T>(arr,n);
        for( int i = n-1 ; i >= 0 ; i-- )
            arr[i] = maxheap.extractMax();
    
    }
    
    template<typename T>
    void heapSort1(T arr[], int n){
    
        MaxHeap<T> maxheap = MaxHeap<T>(n);
        for( int i = 0 ; i < n ; i ++ )
            maxheap.insert(arr[i]);
    
        for( int i = n-1 ; i >= 0 ; i-- )
            arr[i] = maxheap.extractMax();
    
    }
    

    二分搜索 binary sort

    // 用递归的方式写二分查找法
    template<typename T>
    int __binarySearch2(T arr[], int l, int r, T target){
    
        if( l > r )
            return -1;
    
        int mid = (l+r)/2;
        if( arr[mid] == target )
            return mid;
        else if( arr[mid] > target )
            return __binarySearch2(arr, 0, mid-1, target);
        else
            return __binarySearch2(arr, mid+1, r, target);
    
    }
    

    二分搜索树

    template <typename Key, typename Value>
    class BST{
    
    private:
        struct Node{
            Key key;
            Value value;
            Node *left;
            Node *right;
    
            Node(Key key, Value value){
                this->key = key;
                this->value = value;
                this->left = this->right = NULL;
            }
    
            Node(Node *node){
                this->key = node->key;
                this->value = node->value;
                this->left = node->left;
                this->right = node->right;
            }
        };
    
        Node *root;
        int count;
    
    public:
        BST(){
            root = NULL;
            count = 0;
        }
        ~BST(){
            destroy( root );
        }
    
        int size(){
            return count;
        }
    
        bool isEmpty(){
            return count == 0;
        }
    
        void insert(Key key, Value value){
            root = insert(root, key, value);
        }
    
        bool contain(Key key){
            return contain(root, key);
        }
    
        Value* search(Key key){
            return search( root , key );
        }
    
        // 前序遍历
        void preOrder(){
            preOrder(root);
        }
    
        // 中序遍历
        void inOrder(){
            inOrder(root);
        }
    
        // 后序遍历
        void postOrder(){
            postOrder(root);
        }
    
        // 层序遍历
        void levelOrder(){
    
            queue<Node*> q;
            q.push(root);
            while( !q.empty() ){
    
                Node *node = q.front();
                q.pop();
    
                cout<<node->key<<endl;
    
                if( node->left )
                    q.push( node->left );
                if( node->right )
                    q.push( node->right );
            }
        }
    
        // 寻找最小的键值
        Key minimum(){
            assert( count != 0 );
            Node* minNode = minimum( root );
            return minNode->key;
        }
    
        // 寻找最大的键值
        Key maximum(){
            assert( count != 0 );
            Node* maxNode = maximum(root);
            return maxNode->key;
        }
    
        // 从二叉树中删除最小值所在节点
        void removeMin(){
            if( root )
                root = removeMin( root );
        }
    
        // 从二叉树中删除最大值所在节点
        void removeMax(){
            if( root )
                root = removeMax( root );
        }
    
        // 从二叉树中删除键值为key的节点
        void remove(Key key){
            root = remove(root, key);
        }
    
    private:
        // 向以node为根的二叉搜索树中,插入节点(key, value)
        // 返回插入新节点后的二叉搜索树的根
        Node* insert(Node *node, Key key, Value value){
    
            if( node == NULL ){
                count ++;
                return new Node(key, value);
            }
    
            if( key == node->key )
                node->value = value;
            else if( key < node->key )
                node->left = insert( node->left , key, value);
            else    // key > node->key
                node->right = insert( node->right, key, value);
    
            return node;
        }
    
        // 查看以node为根的二叉搜索树中是否包含键值为key的节点
        bool contain(Node* node, Key key){
    
            if( node == NULL )
                return false;
    
            if( key == node->key )
                return true;
            else if( key < node->key )
                return contain( node->left , key );
            else // key > node->key
                return contain( node->right , key );
        }
    
        // 在以node为根的二叉搜索树中查找key所对应的value
        Value* search(Node* node, Key key){
    
            if( node == NULL )
                return NULL;
    
            if( key == node->key )
                return &(node->value);
            else if( key < node->key )
                return search( node->left , key );
            else // key > node->key
                return search( node->right, key );
        }
    
        // 对以node为根的二叉搜索树进行前序遍历
        void preOrder(Node* node){
    
            if( node != NULL ){
                cout<<node->key<<endl;
                preOrder(node->left);
                preOrder(node->right);
            }
        }
    
        // 对以node为根的二叉搜索树进行中序遍历
        void inOrder(Node* node){
    
            if( node != NULL ){
                inOrder(node->left);
                cout<<node->key<<endl;
                inOrder(node->right);
            }
        }
    
        // 对以node为根的二叉搜索树进行后序遍历
        void postOrder(Node* node){
    
            if( node != NULL ){
                postOrder(node->left);
                postOrder(node->right);
                cout<<node->key<<endl;
            }
        }
    
        void destroy(Node* node){
    
            if( node != NULL ){
                destroy( node->left );
                destroy( node->right );
    
                delete node;
                count --;
            }
        }
    
        // 在以node为根的二叉搜索树中,返回最小键值的节点
        Node* minimum(Node* node){
            if( node->left == NULL )
                return node;
    
            return minimum(node->left);
        }
    
        // 在以node为根的二叉搜索树中,返回最大键值的节点
        Node* maximum(Node* node){
            if( node->right == NULL )
                return node;
    
            return maximum(node->right);
        }
    
        // 删除掉以node为根的二分搜索树中的最小节点
        // 返回删除节点后新的二分搜索树的根
        Node* removeMin(Node* node){
    
            if( node->left == NULL ){
    
                Node* rightNode = node->right;
                delete node;
                count --;
                return rightNode;
            }
    
            node->left = removeMin(node->left);
            return node;
        }
    
        // 删除掉以node为根的二分搜索树中的最大节点
        // 返回删除节点后新的二分搜索树的根
        Node* removeMax(Node* node){
    
            if( node->right == NULL ){
    
                Node* leftNode = node->left;
                delete node;
                count --;
                return leftNode;
            }
    
            node->right = removeMax(node->right);
            return node;
        }
    
        // 删除掉以node为根的二分搜索树中键值为key的节点
        // 返回删除节点后新的二分搜索树的根
        Node* remove(Node* node, Key key){
    
            if( node == NULL )
                return NULL;
    
            if( key < node->key ){
                node->left = remove( node->left , key );
                return node;
            }
            else if( key > node->key ){
                node->right = remove( node->right, key );
                return node;
            }
            else{   // key == node->key
    
                if( node->left == NULL ){
                    Node *rightNode = node->right;
                    delete node;
                    count --;
                    return rightNode;
                }
    
                if( node->right == NULL ){
                    Node *leftNode = node->left;
                    delete node;
                    count--;
                    return leftNode;
                }
    
                // node->left != NULL && node->right != NULL
                Node *successor = new Node(minimum(node->right));
                count ++;
    
                successor->right = removeMin(node->right);
                successor->left = node->left;
    
                delete node;
                count --;
    
                return successor;
            }
        }
    };
    
    
    void shuffle( int arr[], int n ){
    
        srand( time(NULL) );
        for( int i = n-1 ; i >= 0 ; i -- ){
            int x = rand()%(i+1);
            swap( arr[i] , arr[x] );
        }
    }
    

    并查集union find

    parent 指针
    namespace UF2{
    
        class UnionFind{
    
        private:
            int* parent;
            int count;
    
        public:
            UnionFind(int count){
                parent = new int[count];
                this->count = count;
                for( int i = 0 ; i < count ; i ++ )
                    parent[i] = i;
            }
    
            ~UnionFind(){
                delete[] parent;
            }
    
            int find(int p){
                assert( p >= 0 && p < count );
                while( p != parent[p] )
                    p = parent[p];
                return p;
            }
    
            bool isConnected( int p , int q ){
                return find(p) == find(q);
            }
    
            void unionElements(int p, int q){
    
                int pRoot = find(p);
                int qRoot = find(q);
    
                if( pRoot == qRoot )
                    return;
    
                parent[pRoot] = qRoot;
            }
        };
    }
    

    基于size的优化

    namespace UF3{
    
        class UnionFind{
    
        private:
            int* parent;
            int* sz; // sz[i]表示以i为根的集合中元素个数
            int count;
    
        public:
            UnionFind(int count){
                parent = new int[count];
                sz = new int[count];
                this->count = count;
                for( int i = 0 ; i < count ; i ++ ){
                    parent[i] = i;
                    sz[i] = 1;
                }
            }
    
            ~UnionFind(){
                delete[] parent;
                delete[] sz;
            }
    
            int find(int p){
                assert( p >= 0 && p < count );
                while( p != parent[p] )
                    p = parent[p];
                return p;
            }
    
            bool isConnected( int p , int q ){
                return find(p) == find(q);
            }
    
            void unionElements(int p, int q){
    
                int pRoot = find(p);
                int qRoot = find(q);
    
                if( pRoot == qRoot )
                    return;
    
                if( sz[pRoot] < sz[qRoot] ){
                    parent[pRoot] = qRoot;
                    sz[qRoot] += sz[pRoot];
                }
                else{
                    parent[qRoot] = pRoot;
                    sz[pRoot] += sz[qRoot];
                }
            }
        };
    }
    

    基于层次rank的优化

    namespace UF3{
    
        class UnionFind{
    
        private:
            int* parent;
            int* rank; // rank[i]表示以i为根的集合所表示的树的层数
            int count;
    
        public:
            UnionFind(int count){
                parent = new int[count];
                rank = new int[count];
                this->count = count;
                for( int i = 0 ; i < count ; i ++ ){
                    parent[i] = i;
                    rank[i] = 1;
                }
            }
    
            ~UnionFind(){
                delete[] parent;
                delete[] rank;
            }
    
            int find(int p){
                assert( p >= 0 && p < count );
                while( p != parent[p] )
                    p = parent[p];
                return p;
            }
    
            bool isConnected( int p , int q ){
                return find(p) == find(q);
            }
    
            void unionElements(int p, int q){
    
                int pRoot = find(p);
                int qRoot = find(q);
    
                if( pRoot == qRoot )
                    return;
    
                if( rank[pRoot] < rank[qRoot] ){
                    parent[pRoot] = qRoot;
                }
                else if( rank[qRoot] < rank[pRoot]){
                    parent[qRoot] = pRoot;
                }
                else{ // rank[pRoot] == rank[qRoot]
                    parent[pRoot] = qRoot;
                    rank[qRoot] += 1;
                }
            }
        };
    }
    

    图论

    稀疏图--邻接表

    // 稀疏图 - 邻接表
    class SparseGraph{
    
    private:
        int n, m;
        bool directed;
        vector<vector<int>> g;
    
    public:
        SparseGraph( int n , bool directed ){
            this->n = n;
            this->m = 0;
            this->directed = directed;
            for( int i = 0 ; i < n ; i ++ )
                g.push_back( vector<int>() );
        }
    
        ~SparseGraph(){
    
        }
    
        int V(){ return n;}
        int E(){ return m;}
    
        void addEdge( int v, int w ){
    
            assert( v >= 0 && v < n );
            assert( w >= 0 && w < n );
    
            g[v].push_back(w);
            if( v != w && !directed )
                g[w].push_back(v);
    
            m ++;
        }
    
        bool hasEdge( int v , int w ){
    
            assert( v >= 0 && v < n );
            assert( w >= 0 && w < n );
    
            for( int i = 0 ; i < g[v].size() ; i ++ )
                if( g[v][i] == w )
                    return true;
            return false;
        }
    };
    

    稠密图--邻接矩阵

    // 稠密图 - 邻接矩阵
    class DenseGraph{
    
    private:
        int n, m;
        bool directed;
        vector<vector<bool>> g;
    
    public:
        DenseGraph( int n , bool directed ){
            this->n = n;
            this->m = 0;
            this->directed = directed;
            for( int i = 0 ; i < n ; i ++ )
                g.push_back( vector<bool>(n, false) );
        }
    
        ~DenseGraph(){
    
        }
    
        int V(){ return n;}
        int E(){ return m;}
    
        void addEdge( int v , int w ){
    
            assert( v >= 0 && v < n );
            assert( w >= 0 && w < n );
    
            if( hasEdge( v , w ) )
                return;
    
            g[v][w] = true;
            if( !directed )
                g[w][v] = true;
    
            m ++;
        }
    
        bool hasEdge( int v , int w ){
            assert( v >= 0 && v < n );
            assert( w >= 0 && w < n );
            return g[v][w];
        }
    };
    

    相关文章

      网友评论

          本文标题:堆/二分搜索树/图

          本文链接:https://www.haomeiwen.com/subject/wzauqftx.html