数据结构与算法-查找

2020-05-15  本文已影响0人  SK_Wang

查找表是由同一类型的数据元素构成的集合。由于集合中的数据元素之间存在着完全松散的换洗,因此查找表是一种非常领边的数据结构。

对查找表经常进行的操作:

静态查找表(Static search table)

顺序表的查找

顺序查找(Sequential Search)的查找过程:从表中最后一个记录开始,逐个进行记录的关键字和给定值的比较,若某个记录的关键字和给定值比较相等,则查找成功,找到所查记录;反之,若知道第一个记录,其关键字和给定值比较不相等,则表明表中没有所查记录,查找不成功。

// 顺序查找
int Sequential_Search(int *a, int n, int key) {
    for (int i = 1; I <= n; i++) {
        if (a[i] == key) {
            return i;
        }
    }
    return 0;
}

int Sequential_Search_Guard(int *a, int n, int key) {
    int i = n;
    a[0] = key;
    while (a[i] != key) {
        i--;
    }
    return i;
}

有序表的查找

折半查找(Binary Search)的查找过程:先确定待查找记录所在的范围,然后珠逐步缩小范围直到找到或找不到该记录为止。

// 折半查找算法
int Binary_Search(int *a, int n, int key) {
    int mid;
    int low = 0;
    int high = n;
    while (low <= high) {
        mid = (high + low) >> 1;
        if (key < a[mid]) {
            high = mid - 1;
        } else if (key > a[mid]) {
            low = mid + 1;
        } else {
            return mid;
        }
    }
    return 0;
}
// 插值查找
int Interpolation_Search(int *a, int n, int key) {
    int mid;
    int low = 0;
    int high = n;
    while (low <= high) {
        mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]);
        if (key < a[mid]) {
            high = mid - 1;
        } else if (key > a[mid]) {
            low = mid + 1;
        } else {
            return mid;
        }
    }
    return 0;
}
//5.斐波拉契查找
int F[100]; /* 斐波那契数列 */
int Fibonacci_Search(int *a, int n, int key) {
    int low, high, mid, i, k;
    low = 1;
    high = n;
    k = 0;
    while (n > F[k] - 1) {
        k++;
    }
    for(i = n; i < F[k] - 1; i++)
        a[i] = a[n];
    
    while (low <= high) {
        mid = low + F[k-1] - 1;
        if (key < a[mid]) {
            high = mid - 1;
            k = k - 1;
        } else if(key > a[mid]){
            low = mid + 1;
            k = k - 2;
        } else {
            if (mid <= n) {
                return mid;
            } else {
                return n;
            }
        }
    }
    return 0;
}

动态查找表 (Dynamic search table)

二叉排序树(Binary sort Tree)或者是一颗空树;或者是具有下列性质的二叉树;

  1. 若它的左子树不空,则左子树上所有结点的值均小于它的跟结点的值;
  2. 若它的右子树不空,则右子树上所有结点的值均大于它的跟结点的值;
  3. 它的左、右子树也分别为二叉树排序树;

代码实现

typedef int Status;

typedef  struct BiTNode {
    int data;
    struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;

// 二叉排序树--查找
Status SearchBST(BiTree T, int key, BiTree f, BiTree *p) {
    if (!T) {
        *p = f;
        return FALSE;
    }
    
    if (T->data == key) {
        *p = T;
        return TRUE;
    } else if (key < T->data) {
        return SearchBST(T->lchild, key, T, p);
    } else {
        return SearchBST(T->rchild, key, T, p);
    }
}

Status InsertBST(BiTree *T, int key) {
    BiTree p, s;
    if (!SearchBST(*T, key, NULL, &p)) {
        s = (BiTree)malloc(sizeof(BiTNode));
        s->data = key;
        s->lchild = s->rchild = NULL;
        
        if (!p) {
            *T = s;
        } else if (key < p->data) {
            p->lchild = s;
        } else {
            p->rchild = s;
        }
        return TRUE;
        
    }
    return FALSE;
}

// 从二叉排序树中删除结点p,并重接它的左或者右子树;
Status Delete(BiTree *p){
    BiTree temp, s;
    if((*p)->rchild == NULL) {
        temp = *p;
        *p = (*p)->lchild;
        free(temp);
    } else if((*p)->lchild == NULL) {
        temp = *p;
        *p = (*p)->rchild;
        free(temp);
    } else {
        temp = *p;
        s = (*p)->lchild;
        while (s->rchild) {
            temp = s;
            s = s->rchild;
        }
        (*p)->data = s->data;
        
        if(temp != *p)
            temp->rchild = s->lchild;
        else
            temp->lchild = s->lchild;
        free(s);
    }
    
    return  TRUE;
}

// 查找结点,并将其在二叉排序中删除;
Status DeleteBST(BiTree *T, int key) {
    if(!*T) {
        return FALSE;
    } else {
        if (key == (*T)->data)
            return Delete(T);
        else if (key < (*T)->data)
            return DeleteBST(&(*T)->lchild, key);
        else
            return DeleteBST(&(*T)->rchild, key);
    }
}
上一篇 下一篇

猜你喜欢

热点阅读