查找
来源:互联网 发布:黑暗法术升级数据 编辑:程序博客网 时间:2024/04/29 18:08
对查找表经常进行的操作有:查询某个给定的元素是否在查找表中,查询某个给定元素的属性,在查找表中插入一个元素,从查找表中删除某个给定的元素。
若只对查找表进行前两种操作,称此类查找表为静态查找表,静态查找表在查找过程中本身不发生变化,对静态查找表进行的操作称为静态查找。
若在查找过程中需要插入表中不存在的元素或者删除表中的一个特定的元素,则此类查找表称为动态查找表,动态查找表在查找过程中可能发生变化,对动态查找表进行的操作称为动态查找。
对于查找算法来说,通常只需要一个或者几个辅助空间。查找过程的主要操作是进行关键字的比较,因此通常以“平均比较次数“来衡量查找算法的优劣。为了确定记录在查找表中的位置,需要和给定的值进行比较的关键字个数的期望值称为查找算法在查找成功的平均查找长度。
顺序查找:从表的一端开始,顺序扫描表,依次将记录的关键字与给定的值进行比较,若某个记录的关键字与给定的值相等,则查找到所查记录,查找成功;若已扫描到了另一端,仍未找到关键字与给定值相等的节点,说明表中没有查找记录,查找失败。
顺序查找的优点是算法比较简单而且适应面广,对表的结构没有要求,数组或是链表存储记录都可以,并且无论记录是否有序都可以查找。缺点是平均查找长度较大,效率比较低,n较大时不适合用顺序查找。
/*链式存储结构的顺序查找*/#include<stdio.h>#include<stdlib.h>typedef struct { int key; struct node *next;} node;node * CreateLink() { node *head, *tail, *ptr; int i, n; head = tail = ptr = NULL; printf("输入链表中元素的个数:"); scanf("%d", &n); for (i = 1; i <= n; i++) { ptr = (node*)malloc(sizeof(node)); printf("输入第%d个节点的key值:", i); scanf("%d", &ptr->key); ptr->next = NULL; if (head == NULL) head = tail = ptr; else { tail->next = ptr; tail = tail->next; } } return head;}node * SequelSearch(node *head, int value) { node * p = head; while (p != NULL) { if (p->key == value) break; else p = p->next; } return p;}void main() { int value; node *ptr, *head; head = CreateLink(); ptr = head; printf("\n链表初始化后,节点key的值为:"); while (ptr != NULL) { printf("%d ", ptr->key); ptr = ptr->next; } printf("\n\n输入要查找的节点的key值:"); scanf("%d", &value); ptr = SequelSearch(head, value); if (ptr != NULL) printf("\n已查找到该节点,查找成功!"); else printf("\n未找到该节点,查找失败!"); printf("\n\n");}
折半查找:要求查找表用顺序存储结构存放且各元素有序排列(升序或降序)
#include<stdio.h>int BinarySearch(int *array, int n, int x) { int low, high, middle; low = 0; high = n - 1; while (low <= high) { middle = (low + high) / 2; if (*(array + middle) == x) return 1; else { if (*(array + middle) >= x) { high = middle - 1; } if (*(array + middle) <= x) { low = middle + 1; } } } return 0;}void main() { int array[10] = { 2,4,5,13,15,20,30,33,43,52 }; int x1 = 20, x2 = 34; if (BinarySearch(array, 10, x1)) printf("已找到%d\n", x1); else printf("未找到%d\n", x1); if (BinarySearch(array, 10, x2)) printf("已找到%d\n", x2); else printf("未找到%d\n", x2);}
分块查找:分块查找要求把一个大的线性表分解成若干块,每块中的节点可以任意存放,但块与块之间必须排序。假设是按关键码值非递减的,那么这种块与块之间必须满足已排序要求,实际上就是对于任意的i,第i块中的所有节点的关键码值都必须小于第i+1块中的所有节点的关键码值。此外,还要建立一个索引表,把每块中的最大关键码值作为索引表的关键码值,按块的顺序存放到一个辅助数组中,显然这个辅助数组是按关键码值非递减排序的。1)首先查找索引表,因为索引表是有序表,可以采用二分查找或顺序查找,确定待查找记录所在的块/字表。2)在已确定的块中进行顺序查找,块内无序,只能使用顺序查找。分块查找的效率介于顺序查找和二分查找之间。