查找法算法 c++实现

1.二分法查找

#include <iostream>

using namespace std;

/******************************
二分查找:又称折半查找,二分查找要求查找的数据必须是有序的,选取中间的数据为基数,
将数据分成两部分与查找关键字进行比较,如果关键字大于基数则在基数右半部分查找(此处
假设安升序排列),否则在左半部分查找。
优点:1、速度快 2、平均性能好
缺点:1、数据必须有序
算法时间复杂度:O(log2n,以2为底n的对数) 空间复杂度:O(n)+辅助空间
******************************/

// 方法一 递归查找
template<typename T>
int half_find(T data[],int left,int right,T target)
{
    if(left>right)
        return -1;

    int mid = left+(right-left)/2; // 防止整数溢出问题
    if(data[mid]>target)
    {
        //right = mid-1;
        return half_find(data,left,mid-1,target);
    }
    else if(data[mid]<target)
    {
        //left = mid+1;
        return half_find(data,mid+1,right,target);
    }
    else
    {
        return mid;
    }
}

// 方法二 非递归查找
template<typename T>
int half_find_T(T data[],int n,T target)
{
    int left = 0;
    int right = n-1;
    while(left<=right)
    {
        int mid = left+(right-left)/2; // 防止整数溢出问题
        if(data[mid]>target)
        {
            right = mid-1;
        }
        else if(data[mid]<target)
        {
            left = mid+1;
        }
        else
        {
            return mid;
        }
    }
    return -1;
}

int main()
{
    int tmpArr[] = {0,1,2,3,4,5,6,7,8,9};
    //int ret = half_find(tmpArr,0,10,5);
    int ret = half_find_T(tmpArr,10,5);
    if(ret != -1)
    {
        cout << "find it!" << endl;
    }
    else
    {
        cout << "can't find it!" << endl;
    }
    cout << "Hello World!" << endl;
    return 0;
}

2.顺序查找

#include<iostream>
using namespace std;
int SequentialSearch(int *a,  int lengh, int key)
{   
    for(int i = 0 ; i < lengh ; i++)
    {
        if(a[i] == key)
        return i;
    }
    return -1;
}
int main()
{
    int arr[] = {2,8,6,7,0,1,3,5,4,9};
	int result, num = 7;
    result = SequentialSearch(arr,sizeof(arr),num);
    if(result == -1)
        cout<<"没找到!"<<endl;
    else
        cout<<"在m["<<result<<"]里找到"<<num<<endl;
    system("pause");
    return 0;
}

3.二叉树

二叉树是每个结点最多有两个子树的树结构,即结点的度最大为2。通常子树被称作”左子树”和”右子树”。二叉树是一个连通的无环图。

二叉树是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:(1)、空二叉树;(2)、只有一个根结点的二叉树;(3)、只有左子树;(4)、只有右子树;(5)、完全二叉树。

二叉树类型:

(1)、满二叉树:深度(层数)为k,且有2^k-1个结点的二叉树。这种树的特点是每一层上的结点数都是最大结点数。即除了叶结点外每一个结点都有左右子树且叶节点都处在最低层。

(2)、完全二叉树:除最后一层外,其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,即叶子结点都是从左到右依次排布。具有n个节点的完全二叉树的深度为floor(long(2n))+1。深度为k的完全二叉树,至少有2(k-1)个结点,至多有(2k)-1个结点。

(3)、平衡二叉树:又被称为AVL树,它是一颗二叉排序树,且具有以下性质:它是一颗空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一颗平衡二叉树。

(4)、斜树:所有的结点都只有左子树(左斜树),或者只有右子树(右斜树)。

(5)、二叉搜素树(或二叉排序树):特殊的二叉树,每个结点都不比它左子树的任意元素小,而且不比它的右子树的任意元素大。二叉搜索树的左右子树也都是二叉搜索树。按中序遍历,则会得到按升序排列的有序数据集。

二叉树不是树的一种特殊情形。

遍历二叉树:按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。对一颗二叉树的遍历有四种情况:先序遍历、中序遍历、后序遍历、按层遍历。

(1)、先序遍历:先访问根结点,再先序遍历左子树,最后再先序遍历右子树,即先访问根结点-------左子树------右子树。

(2)、中序遍历:先中序遍历左子树,然后再访问根结点,最后再中序遍历右子树,即先访问左子树------根结点------右子树。

(3)、后序遍历:先后序遍历左子树,然后再后序遍历右子树,最后再访问根结点,即先访问左子树------右子树------根结点。

(4)、按层遍历:从上到下,从左到右依次访问结点。

下面代码是二叉搜索树的实现,主要包括树的创建、插入、删除、查找、遍历、保存、载入。

#ifndef FBC_CPPBASE_TEST_BINARY_SEARCH_TREE_HPP_
#define FBC_CPPBASE_TEST_BINARY_SEARCH_TREE_HPP_
 
#include <vector>
#include <fstream>
#include <string>
 
namespace binary_search_tree_ {
 
typedef struct info {
	int id; // suppose id is unique
	std::string name;
	int age;
	std::string addr;
} info;
 
typedef struct node {
	info data;
	node* left = nullptr;
	node* right = nullptr;
} node;
 
class BinarySearchTree {
public:
	BinarySearchTree() = default;
	~BinarySearchTree() { DeleteTree(tree); }
 
	typedef std::tuple<int, int, std::string, int, std::string> row; // flag(-1: no node, 0: have a node), id, name, age, addr
 
	int Init(const std::vector<info>& infos); // create binary search tree
	bool Search(int id, info& data) const;
	int Insert(const info& data);
	int Delete(int id); // delete a node
	int Traversal(int type) const; // 0: pre-order, 1: in-order, 2: post-order, 3: level
	int GetMaxDepth() const; // get tree max depth
	int GetMinDepth() const; // get tree min depth
	int GetNodesCount() const; // get tree node count
	bool IsBinarySearchTree() const; // whether or not is a binary search tree
	//bool IsBinaryBalanceTree() const; // whether ot not is a binary balance tree
	int GetMinValue(info& data) const;
	int GetMaxValue(info& data) const;
	int SaveTree(const char* name) const; // tree write in txt file
	int LoadTree(const char* name);
 
protected:
	void PreorderTraversal(const node* ptr) const;
	void InorderTraversal(const node* ptr) const;
	void PostorderTraversal(const node* ptr) const;
	void LevelTraversal(const node* ptr) const;
	void LevelTraversal(const node* ptr, int level) const;
	void DeleteTree(node* ptr);
	void Insert(node* ptr, const info& data);
	const node* Search(const node* ptr, int id) const;
	void IsBinarySearchTree(const node* ptr, bool is_bst) const;
	int GetNodesCount(const node* ptr) const;
	int GetMaxDepth(const node* ptr) const;
	int GetMinDepth(const node* ptr) const;
	//bool IsBinaryBalanceTree(const node* ptr) const;
	node* Delete(node* ptr, int id); // return new root
	node* GetMinValue(node* ptr);
	void NodeToRow(const node* ptr, std::vector<row>& rows, int pos) const;
	void RowToNode(node* ptr, const std::vector<row>& rows, int n, int pos);
 
private:
	node* tree = nullptr;
	bool flag;
};
 
int test_binary_search_tree();
 
} // namespace binary_search_tree_
 
#endif // FBC_CPPBASE_TEST_BINARY_SEARCH_TREE_HPP_
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值