查找算法与二叉排序树、二叉平衡树、B树、哈希表

查找:就是根据给定的某个值,在查找表中确定一个其关键字等于给定值得数据元素(或记录)

顺序表查找:

  很简单的可以直接从头开始循环,找到了就返回。但是这样并不完美,因为每次循环都要判断循环因子i是否越界。然后事实上还可以设置一个哨兵,可以解决这个问题。

int Sequential_Serach(int *a, int n, int key)
{
    int i;
    a[0] = key;//设置a[0]为关键字
    i = n;//从数组尾部开始循环
    while(a[i] != key)
    {
        i--;
    }
    return i;
}

上面的代码,从尾部开始查找,如果找到则返回对应位置,如果找到最开始的a[0],则会返回0,也就是没有查找到。

有序表查找:

  二分查找:就是不停的分成两份呗

  插值查找:根据要查找的关键字key与查找表中的最大最小记录的关键字比较后再查找。

  斐波拉契查找:....

线性索引查找:

  索引就是把一个关键字与它对应的记录相关联的过程。稠密索引,分块索引,倒排索引

二叉排序树:

  若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值

  若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值

  它的左右子树也分别为二叉排序树

二叉排序树的查找:如果小于就在左子树中查找,大于就在右子树中查找

//非递归代码

BSTreeNode *BSTreeNodeFind(BSTreeNode *tree,DataType x) //查找
{
    while (tree)
    {
        if (tree->_data == x)
            return tree;
        else if (tree->_data < x)
            tree = tree->_right;
        else 
            tree = tree->_left;
    }

    return NULL;
}

//递归代码

BSTreeNode *BSTreeNodeFindR(BSTreeNode *tree,DataType x) //查找
{
    if (!tree)
        return NULL;

    if (tree->_data > x)
        BSTreeNodeFindR(tree->_left,x);
    else if (tree->_data < x)
        BSTreeNodeFindR(tree->_right,x);
    else
        return tree;
}

二叉排序树的插入:

比如说现在有{62,88,58,47,35,73,51,99,37,93},我们开始构建一个二叉排序树,则62为根,88 = 62->e,58=62->l,47 = 58->l....就是这么一个简单的规律

//非递归代码
int BSTreeNodeInsert(BSTreeNode **pptree,DataType x) //搜索树的插入
{
    BSTreeNode *parent = NULL;
    BSTreeNode *cur = *pptree;
    if (*pptree == NULL)
    {
        *pptree = BuyTreeNode(x);
        return 0;
    }
    while (cur)
    {
      parent = cur;
      if (cur->_data > x)
          cur = cur->_left;
      else if (cur->_data < x)
          cur = cur->_right;
      else
          return -1;
    }

    if (parent->_data > x)
        parent->_left = BuyTreeNode(x);
    else 
        parent->_right = BuyTreeNode(x);

    return 0;
}
//递归
int BSTreeNodeInsertR(BSTreeNode **tree,DataType x) //搜索树的插入
{
    if(*tree == NULL)
    {
        *tree = BuyTreeNode(x);
        return 0;
    }

    if ((*tree)->_data > x)
        return BSTreeNodeInsertR(&(*tree)->_left,x);
    else if ((*tree)->_data < x)
        return BSTreeNodeInsertR(&(*tree)->_right,x);
    else
        return -1;
}

二叉排序树的删除:

首先查找元素是否在二叉搜索树中,如果不存在,则返回, 否则要删除的结点可能分下面四种情况:
a. 要删除的结点无孩子结点
b. 要删除的结点只有左孩子结点
c. 要删除的结点只有右孩子结点
d. 要删除的结点有左、右孩子结点
情况1可以归类到2或者3
对于上述情况,相应的删除方法如下:
a. 直接删除该结点
b. 删除该结点且使被删除节点的双亲结点指向被删除节点的左孩子结点
c. 删除该结点且使被删除节点的双亲结点指向被删除结点的右孩子结点
d. 在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,在来处理该结点的删除问题

int BSTreeNodeDel(BSTreeNode **tree,DataType x) //删除
{

    BSTreeNode *cur = *tree;
    BSTreeNode *parent = *tree;
    BSTreeNode *del = NULL;

    while (cur)
    {
        if (cur->_data > x)
        {
            parent = cur;
            cur = cur->_left;
        }
        else if (cur->_data < x)
        {
            parent = cur;
            cur = cur->_right;
        }
        else
        {
            del = cur;

            if (cur->_left == NULL) //1、左孩子为空
            {
                if (parent->_left == cur)
                    parent->_left = cur->_right;
                else if (parent->_right == cur)
                    parent->_right = cur->_right;
                else if (parent == cur) //没有父亲节点时
                   *tree = parent->_right;
            }
            else if (cur->_right == NULL) //2、右孩子为空
            {
                if (parent->_left == cur)
                    parent->_left = cur->_left;
                else if (parent->_right == cur)
                    parent->_right = cur->_left;
                else if (parent == cur) //没有父亲节点时
                    *tree = parent->_left;
            }
            else//3、左右孩子都不为空
            {
                BSTreeNode *sub = cur->_right;
                while (sub->_left)
                {
                    parent = sub;
                    sub = sub->_left;
                }

                del = sub;
                cur->_data = sub->_data;

                if (parent->_left == sub)
                    parent->_left = sub->_right;
                else 
                    parent->_right = sub->_right;
            }

            free(del);
            del = NULL;
            return 0;

        }
    }

    return -1;
}

二叉平衡树:是一种每一个节点的左子树和右子树的高度差最多等于1的二叉排序树。

多路查找树:也就是B树,其每一个结点的孩子树可以多于两个,且每一个结点出可以存储多个元素。四种形式,2-3,2-3-4,B,B+

2-3树:

  其中每一个结点都有2或者3个结点

2-3-4树:

B树:

B+树:

散列表查找(哈希表)概述:

猜你喜欢

转载自blog.csdn.net/qq_23905237/article/details/88201656