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_