美文网首页
二分搜索树和链表查词频算法时间对比

二分搜索树和链表查词频算法时间对比

作者: 小伟_be27 | 来源:发表于2019-05-03 11:06 被阅读0次

二分搜索树

性质:
每个节点的键值大于左孩子;
每个节点的键值小于右孩子;
以左右孩子为根的子树仍为二分搜索树
注意:不一定是完全二叉树
查找时间复杂度O(log(n)) ,其实查找所需的最大次数等同于二叉查找树的高度

二分搜索树c++代码实现(递归实现):
#include <iostream>
#include <vector>
#include <string>
#include "SequenceST.h"
#include "FileOps.h"

using namespace std;

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 *root;
    int count;

public:
    BST(){
        root = NULL;
        count = 0;
    }
    ~BST(){
        // TODO: ~BST()
    }

    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 );
    }

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 );
    }
};

链表

性质:
链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的
每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
查找时间复杂度O(n)
插入时间复杂度O(1)

链表c++代码实现
#include <iostream>
#include <cassert>

using namespace std;


template<typename Key, typename Value>
class SequenceST{
private:
    struct Node{
        Key key;
        Value value;
        Node *next;

        Node(Key key, Value value){
            this->key = key;
            this->value = value;
            this->next = NULL;
        }
    };

    Node* head;
    int count;

public:
    SequenceST(){
        head = NULL;
        count = 0;
    }
    ~SequenceST(){
        while( head != NULL){
            Node *node = head;
            head = head->next;
            delete node;
            count --;
        }

        assert( head == NULL && count == 0 );
    }

    int size(){
        return count;
    }

    bool isEmpty(){
        return count == 0;
    };
    //从链表的头部插入
    void insert(Key key, Value value){
        Node *node = head;
        while( node != NULL ){
            if( key == node->key ){
                node->value = value;
                return;
            }
            node = node->next;
        }

        Node *newNode = new Node(key, value);
        newNode->next = head;
        head = newNode;
        count ++;
    }
    //判断链表中是否包含某个键
    bool contain(Key key){

        Node *node = head;
        while( node != NULL ){
            if( key == node->key ){
                return true;
            }
            node = node->next;
        }

        return false;
    }
   //读出链表中键对应的值
    Value* search(Key key){

        Node *node = head;
        while( node != NULL ){
            if( key == node->key ){
                return &(node->value);
            }
            node = node->next;
        }

        return NULL;
    }

    void remove(Key key){

        if( key == head->key ){
            Node* delNode = head;
            head = head->next;
            delete delNode;
            count--;
            return;
        }

        Node *node = head;
        while( node->next != NULL && node->next->key != key )
            node = node->next;

        if( node->next != NULL ){
            Node* delNode = node->next;
            node->next = delNode->next;
            delete delNode;
            count --;
            return;
        }
    }
};

测试代码:

int main() {

    string filename = "bible.txt";
    vector<string> words;
    if( FileOps::readFile(filename, words) ) {

        cout << "There are totally " << words.size() << " words in " << filename << endl;

        cout << endl;


        // test BST
        time_t startTime = clock();
        BST<string, int> bst = BST<string, int>();
        for (vector<string>::iterator iter = words.begin(); iter != words.end(); iter++) {
            int *res = bst.search(*iter);
            if (res == NULL)
                bst.insert(*iter, 1);
            else
                (*res)++;
        }

        cout << "'god' : " << *bst.search("god") << endl;
        time_t endTime = clock();
        cout << "BST , time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s." << endl;

        cout << endl;


        // test SST
        startTime = clock();
        SequenceST<string, int> sst = SequenceST<string, int>();
        for (vector<string>::iterator iter = words.begin(); iter != words.end(); iter++) {
            int *res = sst.search(*iter);
            if (res == NULL)
                sst.insert(*iter, 1);
            else
                (*res)++;
        }

        cout << "'god' : " << *sst.search("god") << endl;

        endTime = clock();
        cout << "SST , time: " << double(endTime - startTime) / CLOCKS_PER_SEC << " s." << endl;

    }

    return 0;
}

最后结果:

'god' : 2101
BST ,time : 0.599448 s.
'god' : 2301
SST ,time: 55.1001 s.

相关文章

  • 二分搜索树和链表查词频算法时间对比

    二分搜索树 性质:每个节点的键值大于左孩子;每个节点的键值小于右孩子;以左右孩子为根的子树仍为二分搜索树注意:不一...

  • 数据结构java描述

    接口 栈 队列 集合 并查集 映射 数组 链表 栈 数组实现 链表实现 队列 数组实现 链表实现 二分搜索树 集合...

  • Swift 算法实战二(二叉树、二分搜索)

    Swift 算法实战一(集合,字典,链表,栈,队列等算法) Swift 算法实战二(二叉树、二分搜索) 前言 这是...

  • Swift 算法实战一(集合,字典,链表,栈,队列等算法)

    Swift 算法实战一(集合,字典,链表,栈,队列等算法) Swift 算法实战二(二叉树、二分搜索) 前言 用 ...

  • 面试题

    面试题总结 1、算法问题,链表反转、二分搜索、深度搜索、广度搜索、常见算法 时间复杂度(大 O 表示) 2、OC相...

  • 算法-二分搜索算法

    算法:二分搜索算法(折半查找算法)时间复杂度: 二分搜索算法概述 二分搜索算法伪代码 二分搜索算法实现 二分搜索算...

  • 算法草稿

    常用算法集合 字符处理算法数组与查找链表树算法思路 递归、动态规划、BFS/DFS、双指针、二分法搜索数据结构的...

  • 高频题

    字符串 数学 数组 二叉树 二分查找 链表 动态规划 贪心算法 堆 广度优先搜索 深度优先 哈希表 回溯算法 设计

  • Aha! Algorithms

    1. 涉及的数据结构 栈、队列、链表、树、并查集、堆、图 2. 涉及的算法 排序、枚举、深度和广度优先搜索、图的遍...

  • C++编写算法(六)——查找问题,二叉查找树

    一、二叉查找树 前面一章分析了二分查找这种算法。 要支持高效的插入操作,我们需要链式的数据结构,但是链表不能二分查...

网友评论

      本文标题:二分搜索树和链表查词频算法时间对比

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