2023数据结构考研复习-查找

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2023数据结构考研复习-查找相关的知识,希望对你有一定的参考价值。

2023数据结构考研复习-查找(七)

1. 二分查找递归

算法的基本思想:根据查找的起始位置和终止位置,将查找序列一分为二,判断所查找的关键字在哪一部分,然后用新的序列的起始位置和终止位置递归求解。

int BinSearchRec (int[] arr, int key, int low, int high) 
    if (low > high) 
        return 0;
    mid = (low + high) / 2;
    if (key > arr[mid])
        BinSearchRec (arr, mid + 1, high);
    else if (key < arr[mid])
        BinSearchRec (arr, mid + 1, high);
    else
        return mid;

算法把规模为n的复杂问题经过多次递归调用转化为规模减半的子问题求解。时间复杂度为O(log2n),算法中用到了一个递归工作栈,其规模与递归深度有关,也是O(log2n)。

2. 检索概率不等的顺序检索算法

线性表中各结点的检索概率不等时,可用如下策略提高顺序检索的效率:若找到指定的结点,则将该结点和其前驱结点(若存在)交换,使得经常被检索的结点尽量位于表的前端。试设计在顺序结构和链式结构的线性表上实现上述策略的顺序检索算法。

int search(int r[], int k) 
    int i = 0;
    while (r[i].key != k && i < n)
        i++;
    if (i < n && i > 0) 
        temp = r[i];
        r[i] = r[i-1];
        r[i-1] = temp;
        return --i;
     else 
        return -1;
    

3. 检查二叉排序树

试编写一个算法,判断给定的二叉树是否是二叉排序树。

对二叉排序树来说,其中序遍历序列为一个递增有序序列。因此,对给定的二叉树进行中序遍历,若始终能保持前一个值比后一个值小,则说明该二叉树是一棵二叉排序树。算法实现如下:

KeyType pre = -32767;
int JudgeBST(BiTree bt) 
    int b1, b2;
    if (bt == NULL)
        return 1;
    else 
        b1 = JudgeBST (bt.lchild);
        if (b1 == 0 || pre >= bt->data)
            return 0;
        pre = bt->data;
        b2 = JudgeBST (bt.rchild);
        return b2;
    

4. 获取结点的层次

设计一个算法,求出指定结点在给定二叉排序树中的层次。

算法思想:设二叉树采用二叉链表存储结构。在二叉排序树中,查找一次就下降一层。因此,查找该结点所用的次数就是该结点在二叉排序树中的层次。采用二叉排序树非递归查找算法,用n保存查找层次,每查找一次,n就加1,直到找到相应的结点。

算法如下:

int level (BiTree bt, BSTNode *p) 
    int n = 0;
    BiTree t = bt;
    if (bt != NULL) 
        n++;
        while (t->data != p->data) 
            if (p->data < t->data)
                t = t->lchild;
            else
                t = t->rchild;
            n++;
        
    
    return n;

5. 判断是否为平衡二叉树

利用二叉树遍历的思想编写一个判断二叉树是否是平衡二叉树的算法。

设置二叉树的平衡标记balance,以标记返回二叉树bt是否为平衡二叉树,若为平衡二叉树,则返回1,否则返回0;h为二叉树bt的高度。采用后序遍历的递归算法:

1)若bt为空,则高度为0,balance=1。
2)若bt仅有根结点则高度为1, balance=1。
3)否则,对bt 的左、右子树执行递归运算,返回左、右子树的高度和平衡标记,bt的高度为最高子树的高度加1。

  • 若左、右子树的高度差大于1,则balance=0;
  • 若左、右子树的高度差小于等于1,且左、右子树都平衡时,balance=1,否则balance=0。

算法如下:

class solution 
    public boolean isBalanced ( TreeNode root) 
        if( root == null) 
            return true;
        if(isBalanced(root.left) && isBalanced(root.right) && Math.abs(height(root.left)-height( root.right)) <= 1)
            return true;
     else 
        return false;
    

public int height(TreeNode root) //求二叉树高度
    if(root == null) 
        return 0;
    return Math.max(height(root.left), height(root.right)) + 1;
void Judge_AVL (BiTree bt, int &balance, int &h) 
    int bl = 0, br = 0, hl = 0, hr = 0;  // 左右子树平衡标记和高度
    if (bt == NULL) 
    
        h = 0;
        balance = 1;
    
    else if (bt->lchild == NULL && bt->rchild == NULL)
    
        h = 1;
        balance = 1;
    
    else
    
        Judge_AVL (bt->lchild, b1, h1);
        Judge_AVL (bt->rchild, br, hr);
        h = max(hl, hr) + 1;
        if (abs(hl - hr) < 2)  // 子树高度差绝对值<2
            balance = bl & br;
        else
            balance = 0;
    

6. 二叉排序树的最小和最大的关键字

设计一个算法,求出给定二叉排序树中最小和最大的关键字。

在一棵二叉排序树中,最左下结点即为关键字最小的结点,最右下结点即为关键字最大的结点,本算法只要找出这两个结点即可,而不需要比较关键字。

算法如下:

KeyType MinKey (BSTNode *bt) 
    while (bt->lchild != NULL)
        bt = bt->lchild;
    return bt->data;    

KeyType MmaxKey (BSTNode *bt) 
    while (bt->rchild != NULL)
        bt = bt->rchild;
    return bt->data;    

7. 大到小输出二叉排序树中所有值不小于k的关键字

设计一个算法,从大到小输出二叉排序树中所有值不小于k的关键字。

由二叉排序树的性质可知,右子树中所有的结点值均大于根结点值,左子树中所有的结点值均小于根结点值。为了从大到小输出,先遍历右子树,再访问根结点,后遍历左子树。

算法如下:

void Output (BSTNode *bt, KeyType k) 
    if (bt == NULL)
        return;
    if (bt->rchild != NULL)
        Output (bt->rchild, k);
    if (bt->data >= k)
        printf("%d", bt->data);
    if (bt->lchild != NULL)
        Output (bt->lchild, k);

中序遍历+栈:

Stack<BSTNode> stack;
void Output (BSTNode *bt, KeyType k) 
    if (bt == NULL)
        return;
    if (bt->lchild != NULL)
        Output (bt->rchild, k);
    if (bt->data >= k)
        PUSH(stack, bt->data);
    if (bt->rchild != NULL)
        Output (bt->lchild, k);

void print() 
    while (!isEmpty(stack))
        printf("%d", POP(stack));

8. 查找二叉排序树的第k小元素

编写一个递归算法,在一棵有n个结点的、随机建立起来的二叉排序树上查找第k ( 1≤k ≤n)小的元素,并返回指向该结点的指针。

  • 要求算法的平均时间复杂度为O(log2n)。
  • 二叉排序树的每个结点中除data,lchild,rchild等数据成员外,增加一个count成员,保存以该结点为根的子树上的结点个数。

BSTNode *Search_Small (BSTNode *t, int k) 
    // 树节点增加一个count数据成员,存储以该节点为根子树的结点个数
    if (k < 1 || k > t->count)
        return NULL;
    if (t.lchild = NULL)
    
         if (k == 1)
            return t;
        else
            return Search_Small(t->rchild, k-1);
    
    else 
    
        if (t->lchild->count == k-1)
            return t;
        if (t->lchild->count > k-1)
            return Search_Small(t->lchild, k);
        if (t->lchild->count < k-1)
            return Search_Small(t->rchild, k-(t->lchild->count+1));
    

最大查找长度取决于树的高度。由于二叉排序树是随机生成的,其高度应是O(log2n),算法的时间复杂度为O(log2n)。

以上是关于2023数据结构考研复习-查找的主要内容,如果未能解决你的问题,请参考以下文章

2023数据结构考研复习-查找

2023数据结构考研复习-查找

2023数据结构考研复习-栈队列和数组

2023数据结构考研复习-栈队列和数组

2023数据结构考研复习-串

2023数据结构考研复习-串