顺序查找
思路
暴力搜索,从头到尾遍历数组,找到该元素就返回元素下标,否则返回-1。
代码
#include<stdio.h>
#include "malloc.h"
#include<stdlib.h>
#include<time.h>
//定义查找表结构体
typedef struct
{
int *data;
int TableLen;
}SSTable;
//输出查找表
void print(SSTable* L)
{
SSTable* p = L;
for (int i = 0; i < L->TableLen; ++i)
{
printf("%d ", p->data[i]);
}
}
int Search_Seq(SSTable* L, int key) {
int i;
for (i = 0; i < L->TableLen && L->data[i] != key; ++i);
return i == L->TableLen ? -1 : i;
}
void test()
{
//建立查找表
SSTable* L = (SSTable*)malloc(sizeof(SSTable));
if (L == NULL) {
printf("内存分配不成功!\n");
}
else
{
L->TableLen = 10;
L->data = (int*)malloc(L->TableLen * sizeof(int));
srand(time(0));
for (int i = 0; i < L->TableLen; ++i)
{
L->data[i] = rand() % 100;//取0-99的随机数 0-99,都为原值,100-199为0-99,以此类推
}
printf("原始序列为:\n");
print(L);
printf("\n%d是序列第%d个元素\n", L->data[5],Search_Seq(L, L->data[5])+1);
}
}
int main()
{
test();
}
有序优化
如果待查找序列是有序的,则在从头到尾的遍历过程中,遇到大于key的元素,说明后面所有元素都大于key。无需继续查找直接返回-1.
int Search_Seq(SSTable* L, int key) {
int i;
for (i = 0; i < L->TableLen && L->data[i] != key; ++i) {
if (L->data[i] > key)
return -1;
}
return i == L->TableLen ? -1 : i;
}
链表实现
思路
暴力搜索,从头到尾遍历节点,找到该元素就返回元素值,否则(遍历到结尾,为NULL)返回-1。
代码
易错点:
1,定义链表结构体之前,要先加名称SSTable,否则后面定义SSTable* next;会报错。
2,链表动态分配内存时,不能直接用L,要新建p来遍历,因为L为头结点,不能指向L=L->next操作。
3,执行查找时最后返回了p,那么p在函数中应该为全局变量
#include<stdio.h>
#include "malloc.h"
#include<stdlib.h>
#include<time.h>
//定义查找表结构体
typedef struct SSTable//必须先加SSTable,否则next指针无法使用
{
int data;
SSTable* next;
}SSTable;
//输出查找表
void print(SSTable* L)
{
SSTable* p = L->next;//带头结点的输出要从L->next开始
for (int i = 0; i < L->data; ++i)//L为头结点不能动 否则每次遍历就会改变条件
{
printf("%d ", p->data);
p = p->next;
}
}
int Search_Seq(SSTable* L, int key) {
SSTable* p = L->next;
if (p != NULL) {
while (p != NULL && p->data != key) {
p = p->next;
}
}
return p == NULL ? -1 : p->data;//p必须为全局变量,返回的是值不是下标
}
void test()
{
int key;
//建立链表
SSTable* L = (SSTable*)malloc(sizeof(SSTable));
if (L == NULL) {
printf("内存分配不成功!\n");
}
else
{
L->data = 10;
srand(time(0));
SSTable* p = L;
for (int i = 0; i < L->data; ++i)
{
p->next = (SSTable*)malloc(sizeof(SSTable));
if (p->data) {
p = p->next;
p->data = rand() % 100;//取0-99的随机数 0-99,都为原值,100-199为0-99,以此类推
if (i == 5)
key = p->data;
}
}
p->next=NULL;
printf("原始序列为:\n");
print(L);
printf("\n在序列中找到元素%d\n", Search_Seq(L, key));
}
}
int main()
{
test();
}
折半查找
思路
只适合有序顺序表(数组);key与序列中间位置元素对比,等于返回key;小于查找左子表,大于查找右子表。直到找到key或者low>high,找不到返回-1。
代码
#include<stdio.h>
#include "malloc.h"
#include<stdlib.h>
#include<time.h>
//定义查找表结构体
typedef struct
{
int* data;
int TableLen;
}SSTable;
//输出查找表
void print(SSTable* L)
{
SSTable* p = L;
for (int i = 0; i < L->TableLen; ++i)
{
printf("%d ", p->data[i]);
}
}
int Binary_Search(SSTable* L, int key) {
int low = 0, high = L->TableLen - 1, mid;
while (low <= high) {
mid = (low + high) / 2;
if (L->data[mid] == key)
return mid;
else if (L->data[mid] > key)
high = mid - 1;
else
low = mid + 1;
}
return -1;
}
void test()
{
//建立查找表
SSTable* L = (SSTable*)malloc(sizeof(SSTable));
if (L == NULL) {
printf("内存分配不成功!\n");
}
else
{
L->TableLen = 10;
L->data = (int*)malloc(L->TableLen * sizeof(int));
srand(time(0));
for (int i = 0; i < L->TableLen; ++i)
{
L->data[i] = i;//取0-99的随机数 0-99,都为原值,100-199为0-99,以此类推
}
printf("原始序列为:\n");
print(L);
printf("\n%d是序列第%d个元素\n", L->data[5], Binary_Search(L, L->data[5]) + 1);
}
}
int main()
{
test();
}