数据结构实验报告-查找

     

一、实验名称

实验9 查找

二、实验内容:

1.分别采用顺序查找、折半查找、二叉排序树、平衡二叉树、B.树和哈希表算法实现对简单的整型数组的查找功能。

源码:
#include <stdio.h>

#include <stdlib.h>

// 顺序查找

int sequentialSearch(int arr[], int n, int target) {

    for (int i = 0; i < n; i++) {

        if (arr[i] == target) {

            return i;

        }

    }

    return -1; // 未找到

}

// 折半查找(二分查找)

int binarySearch(int arr[], int n, int target) {

    int left = 0, right = n - 1;

    while (left <= right) {

        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {

            return mid;

        }

        else if (arr[mid] < target) {

            left = mid + 1;

        }

        else {

            right = mid - 1;

        }

    }

    return -1; // 未找到

}

// 二叉排序树

typedef struct treeNode {

    int data;

    struct treeNode* left;

    struct treeNode* right;

} TreeNode;

// 插入节点

TreeNode* insert(TreeNode* root, int data) {

    if (root == NULL) {

        TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));

        newNode->data = data;

        newNode->left = newNode->right = NULL;

        return newNode;

    }

    if (data < root->data) {

        root->left = insert(root->left, data);

    }

    else if (data > root->data) {

        root->right = insert(root->right, data);

    }

    return root;

}

// 查找节点

TreeNode* search(TreeNode* root, int target) {

    if (root == NULL || root->data == target) {

        return root;

    }

    if (target < root->data) {

        return search(root->left, target);

    }

    else {

        return search(root->right, target);

    }

}

// 平衡二叉树、B 树和哈希表的实现可以比较复杂,这里暂时提供以上三种算法的实现示例,可根据需求进一步扩展。

int main() {

    int arr[] = { 5, 10, 15, 20, 25, 30, 35, 40 };

    int n = sizeof(arr) / sizeof(arr[0]);

    // 顺序查找

    int target1 = 15;

    int index1 = sequentialSearch(arr, n, target1);

    if (index1 != -1) {

        printf("顺序查找:找到 %d 在数组中的位置:%d\n", target1, index1);

    }

    else {

        printf("顺序查找:未找到 %d\n", target1);

    }

    // 折半查找

    int target2 = 30;

    int index2 = binarySearch(arr, n, target2);

    if (index2 != -1) {

        printf("折半查找:找到 %d 在数组中的位置:%d\n", target2, index2);

    }

    else {

        printf("折半查找:未找到 %d\n", target2);

    }

    // 二叉排序树

    TreeNode* root = NULL;

    for (int i = 0; i < n; i++) {

        root = insert(root, arr[i]);

    }

    int target3 = 20;

    TreeNode* result = search(root, target3);

    if (result != NULL) {

        printf("二叉排序树:找到 %d\n", target3);

    }

    else {

        printf("二叉排序树:未找到 %d\n", target3);

    }

    return 0;

}

2.在实验2中的学生成绩管理系统使用的是链表存储,这里用二叉排序树重新组织学生数据,实现按学生姓名进行查找的功能。

源码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct student {

    char name[50];

    int age;

    struct student* left;

    struct student* right;

} Student;

// 插入节点

Student* insert(Student* root, const char* name, int age) {

    if (root == NULL) {

        Student* newStudent = (Student*)malloc(sizeof(Student));

        strcpy_s(newStudent->name, sizeof(newStudent->name), name);

        newStudent->age = age;

        newStudent->left = newStudent->right = NULL;

        return newStudent;

    }

    if (strcmp(name, root->name) < 0) {

        root->left = insert(root->left, name, age);

    }

    else {

        root->right = insert(root->right, name, age);

    }

    return root;

}

// 查找节点

Student* search(Student* root, const char* name) {

    if (root == NULL || strcmp(root->name, name) == 0) {

        return root;

    }

    if (strcmp(name, root->name) < 0) {

        return search(root->left, name);

    }

    else {

        return search(root->right, name);

    }

}

// 中序遍历二叉排序树(用于打印输出)

void inorderTraversal(Student* root) {

    if (root != NULL) {

        inorderTraversal(root->left);

        printf("姓名:%s,年龄:%d\n", root->name, root->age);

        inorderTraversal(root->right);

    }

}

int main() {

    Student* root = NULL;

    // 插入学生数据

    root = insert(root, "Alice", 20);

    root = insert(root, "Bob", 22);

    root = insert(root, "Cathy", 21);

    root = insert(root, "David", 23);

    root = insert(root, "Emily", 19);

    // 查找学生数据

    char searchName[50];

    printf("请输入要查找的学生姓名:");

    scanf_s("%s", searchName, sizeof(searchName));

    Student* result = search(root, searchName);

    if (result != NULL) {

        printf("找到学生:姓名:%s,年龄:%d\n", result->name, result->age);

    }

    else {

        printf("未找到该学生信息。\n");

    }

    // 打印所有学生数据(中序遍历)

    printf("所有学生数据如下:\n");

    inorderTraversal(root);

    return 0;

}

3.扩充2中的查找功能,实现同时按姓名、学号进行查找。

源码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct student {

    char name[50];

    int age;

    int studentId;

    struct student* left;

    struct student* right;

} Student;

// 插入节点

Student* insert(Student* root, const char* name, int age, int studentId) {

    if (root == NULL) {

        Student* newStudent = (Student*)malloc(sizeof(Student));

        strcpy_s(newStudent->name, sizeof(newStudent->name), name);

        newStudent->age = age;

        newStudent->studentId = studentId;

        newStudent->left = newStudent->right = NULL;

        return newStudent;

    }

    if (studentId < root->studentId) {

        root->left = insert(root->left, name, age, studentId);

    }

    else {

        root->right = insert(root->right, name, age, studentId);

    }

    return root;

}

// 查找节点(同时按姓名和学号进行查找)

Student* search(Student* root, const char* name, int studentId) {

    if (root == NULL || (strcmp(root->name, name) == 0 && root->studentId == studentId)) {

        return root;

    }

    if (strcmp(name, root->name) < 0 || (strcmp(name, root->name) == 0 && studentId < root->studentId)) {

        return search(root->left, name, studentId);

    }

    else {

        return search(root->right, name, studentId);

    }

}

// 中序遍历二叉排序树(用于打印输出)

void inorderTraversal(Student* root) {

    if (root != NULL) {

        inorderTraversal(root->left);

        printf("姓名:%s,年龄:%d,学号:%d\n", root->name, root->age, root->studentId);

        inorderTraversal(root->right);

    }

}

int main() {

    Student* root = NULL;

    // 插入学生数据

    root = insert(root, "Alice", 20, 1001);

    root = insert(root, "Bob", 22, 1002);

    root = insert(root, "Cathy", 21, 1003);

    root = insert(root, "David", 23, 1004);

    root = insert(root, "Emily", 19, 1005);

    // 查找学生数据

    char searchName[50];

    int searchStudentId;

    printf("请输入要查找的学生姓名:");

    scanf_s("%s", searchName, sizeof(searchName));

    printf("请输入要查找的学生学号:");

    scanf_s("%d", &searchStudentId);

    Student* result = search(root, searchName, searchStudentId);

    if (result != NULL) {

        printf("找到学生:姓名:%s,年龄:%d,学号: %d\n", result->name, result->age, result->studentId);

    }

    else {

        printf("未找到该学生信息。\n");

    }

    // 打印所有学生数据(中序遍历)

    printf("所有学生数据如下:\n");

    inorderTraversal(root);

    return 0;

}

4.继续扩充3的查找功能,给系统“内置”种简单的查询语言,使用该查询语言可以方便地实现查询功能。首先给出该语言的语法格式:

select姓名,成绩from成绩表where成绩> 90

源码:
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

typedef struct student {

    char name[50];

    int age;

    int studentId;

    int score;

    struct student* left;

    struct student* right;

} Student;

void inorderTraversal(Student* root);

void inorderTraversalWithCondition(Student* root, int threshold);

// 函数用于插入学生数据

// 函数用于按学号查找学生节点

// 查询语言解析与执行

void query(Student* root, const char* query) {

    char query_copy[100];

    strcpy(query_copy, query);

    // 解析查询语句

    char* select = strtok(query_copy, " ");

    char* column = strtok(NULL, ",");

    char* from = strtok(NULL, " ");

    char* table = strtok(NULL, " ");

    char* where = strtok(NULL, " ");

    char* condition = strtok(NULL, " ");

    if (select == NULL || column == NULL || from == NULL || table == NULL || where == NULL || condition == NULL) {

        printf("查询语句格式错误。\n");

        return;

    }

    // 提取阈值

    int threshold = atoi(condition);

    // 执行查询操作

    printf("查询结果:\n");

    inorderTraversalWithCondition(root, threshold);

}

// 中序遍历二叉排序树满足条件的节点(查询结果)

void inorderTraversalWithCondition(Student* root, int threshold) {

    if (root != NULL) {

        inorderTraversalWithCondition(root->left, threshold);

        if (root->score > threshold) {

            printf("姓名:%s,成绩:%d\n", root->name, root->score);

        }

        inorderTraversalWithCondition(root->right, threshold);

    }

}

int main() {

    Student* root = NULL;

    // 插入学生数据(包括成绩)

    // 查询学生成绩大于90的学生信息

    query(root, "select name, score from score_table where score 95");

    // 打印所有学生数据(中序遍历)

    return 0;

}

阅读上面的查询语句,通过直观感觉可以猜出该语句的功能大概是选出所有成绩大于90分的学生的姓名和成绩信息。

三、心得体会:

在编写代码解决问题的过程中,我深刻体会到了对于输入的处理至关重要。无论是从用户输入的查询语句中提取信息,还是对数据的有效检索和处理,都需要对输入进行严格的验证和解析。特别是在处理复杂的查询语句时,逐个检查关键字和条件能够确保程序的稳健性和正确性。通过对输入的仔细处理,可以避免因为用户输入不规范而导致的错误,提高程序的可靠性和稳定性。因此,编程中的“查找”不仅仅局限于数据检索,更涉及到对输入信息的全面分析和处理,这种细致入微的“查找”精神,对程序的健壮性和用户体验有着重要的影响。在今后的编程工作中,我将更加注重对输入的处理,以提升代码的质量和可靠性。

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值