数据结构和算法笔记(2)基础算法模板

有很多的基础算法经常会用到,但是又容易写错。而网上查到的实现又五花八门、良莠不齐,故在此整理记录。

本文的目录如下:

1.二分查找    2.并查集    3.最大公约数    4.Trie树(前缀树)

 

1.二分查找

一个细节就是计算middle时,用 (left + right) / 2 容易数值溢出,所以改成 middle = left + (right - left) / 2.

c++实现:

#define LEFT_BOUND 0
#define RIGHT_BOUND 100

int check(const int &middle){
    // TODO: return -1 or 0 or 1
}

int main() {
    int left = LEFT_BOUND, right = RIGHT_BOUND;
    int middle, flag;
    while (left <= right){
        middle = left + (right - left) / 2;  // 防数值溢出
        flag = check(middle);
        if (flag == 0){
            return middle;
        }
        else if (flag == -1){
            left = middle + 1;
        }
        else{
            right = middle - 1;
        }
    }
    return -1;
}

 

2.并查集

c++实现:

// Union-Find Set, STL style
class UF {
public:
	UF(int n) {
		count = n;
		for (int i = 0; i < n; ++i) {
			parent.push_back(i);
			rank.push_back(0);
		}
	}

	int find(int i) { // path compression
		if (parent[i] != i) parent[i] = find(parent[i]);
		return parent[i];
	}

	void Union(int x, int y) { // union with rank
		int rootx = find(x);
		int rooty = find(y);
		if (rootx != rooty) {
			if (rank[rootx] > rank[rooty]) parent[rooty] = rootx;
			else if (rank[rootx] < rank[rooty]) parent[rootx] = rooty;
			else {
				parent[rooty] = rootx; rank[rootx] += 1;
			}
			--count;
		}
	}

	int size() const {
		return count;
	}

	void clear() {
		parent.clear();
		rank.clear();
		count = 0;
	}

private:
	vector parent;
	vector rank;
	int count; // # of connected components
};

 

3.最大公约数

c++实现:

// while实现
int gcd(int a, int b){
    while (b != 0){
        int tmp = a % b;
        a = b;
        b = tmp;
    }
    return a;
}

// 递归实现
unsigned int gcd(unsigned int a, unsigned int b) {
    return b == 0 ? a : gcd(b, a % b);
}

 

4.Trie树(前缀树)

c++实现:

class Trie{
public:
    bool isLeaf = false;
    Trie* next[26] = { nullptr };
    
    Trie() {}

    void insert(const string& word) {
        Trie* root = this;
        for (const auto& w : word) {
            if (root->next[w - 'a'] == nullptr)
                root->next[w - 'a'] = new Trie();
            root = root->next[w - 'a'];
        }
        root->isLeaf = true;
    }

    bool search(const string& word) {
        Trie* root = this;
        for (const auto& w : word) {
            if (root->next[w - 'a'] == nullptr)
                return false;
            root = root->next[w - 'a'];
        }
        return root->isLeaf;
    }
};

 

你可能感兴趣的:(数据结构和算法)