【数据结构】实验:查找和排序算法

目录

一、实验目的

二、实验要求

三、核心代码

四、实验记录

五、总结

六、完整报告和成果文件提取链接


一、实验目的

  1. 掌握常用查找方法的基本思想及其实现技术;
  2. 了解各种查找方法的优缺点和适用范围,能对相关的算法进行性能分析
  3. 掌握常用排序方法的基本思想及其实现技术。
  4. 了解各种排序方法的优缺点和适用范围,能对相关的算法进行性能分析

二、实验要求

  1. 设计一个可实现各种查找的演示程序(如学生信息表)。
  2. 设计一个可实现各种排序的演示程序(如学生信息表)

方法提示:用顺序表存储,学生信息表可以直接从某个文件中导入。

参考数据结构(在实验2的基础上进行查找和排序)

typedef struct

{     char no[10];

       char name[10];

       int score[5];

       int total;

}student;

typedef struct

{

       student stu[MAXSIZE];

       int len;

}SeqList;

1. 实现下列六种查找:(1)顺序查找;(2)二分查找;(3)二叉排序树的查找;(必须实现顺序查找)

2. 实现下列六种排序:(1)冒泡;(2)直接插入排序;(3)选择排序;(4)快速排序; (5)希尔排序     ;(6)堆排序(至少实现2种排序算法)

三、核心代码

二分查找

int BinarySearch(SeqList *list, char *name) {
    int low = 0;
    int high = list->len - 1;
    while (low <= high) {
        int mid = low + (high - low) / 2;
        int res = strcmp(list->stu[mid].name, name);
        if (res == 0) {
            return mid; // 找到
        } else if (res < 0) {
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }
    return -1; // 未找到
}

二叉排序树的插入 

TreeNode* InsertTreeNode(TreeNode *root, student data) {
    if (root == NULL) {
        root = (TreeNode*)malloc(sizeof(TreeNode));
        root->data = data;
        root->left = root->right = NULL;
    } else if (strcmp(data.name, root->data.name) < 0) {
        root->left = InsertTreeNode(root->left, data);
    } else {
        root->right = InsertTreeNode(root->right, data);
    }
    return root;
}

二叉排序树的查找

TreeNode* SearchTreeNode(TreeNode *root, char *name) {
    if (root == NULL || strcmp(root->data.name, name) == 0) {
        return root;
    }
    if (strcmp(name, root->data.name) < 0) {
        return SearchTreeNode(root->left, name);
    } else {
        return SearchTreeNode(root->right, name);
    }
}

堆排序的辅助函数 

void Heapify(student arr[], int n, int i) {
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    if (left < n && strcmp(arr[left].name, arr[largest].name) > 0)
        largest = left;
    if (right < n && strcmp(arr[right].name, arr[largest].name) > 0)
        largest = right;
    if (largest != i) {
        student swap = arr[i];
        arr[i] = arr[largest];
        arr[largest] = swap;
        Heapify(arr, n, largest);
    }
}

堆排序

void HeapSort(SeqList *list) {
    int n = list->len;
    int i;
    for (i = n / 2 - 1; i >= 0; i--)
        Heapify(list->stu, n, i);
    for (i = n - 1; i > 0; i--) {
        student temp = list->stu[0];
        list->stu[0] = list->stu[i];
        list->stu[i] = temp;
        Heapify(list->stu, i, 0);
    }
}

  快速排序的辅助函数

int Partition(student arr[], int low, int high) {
    student pivot = arr[high];
    int i = (low - 1); 
    int j;
    for (j = low; j <= high - 1; j++) {
        if (strcmp(arr[j].name, pivot.name) < 0) {
            i++;
            student temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    student temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return (i + 1);
}

快速排序

void QuickSort(student arr[], int low, int high) {
    if (low < high) {
        int pi = Partition(arr, low, high);
        QuickSort(arr, low, pi - 1);
        QuickSort(arr, pi + 1, high);
    }
}

四、实验记录

实验时输入多组测试数据,粘贴运行结果截图

(1) 学生信息表直接从学生信息表文件中导入,学生信息可以进行修改。进行aa学生的序号查找以及序号查找学生姓名的操作。实现顺序查找以及二分查找、二叉排序树查找。

(2) 对学生信息表实现排序功能,进行希尔排序、堆排序、快速排序的功能。

五、总结

1、查找方法

(1)顺序查找:从列表的第一个元素开始,逐个比较,直到找到目标元素或遍历完整个列表。时间复杂度为O(n)。

(2)二分查找:在有序列表中,取中间元素进行比较,如果目标值等于中间元素,则查找成功;如果目标值小于中间元素,则在左半部分继续查找;如果目标值大于中间元素,则在右半部分继续查找。时间复杂度为O( )。

(3)二叉排序树的查找:在二叉排序树中,根据目标值的大小,选择左子树或右子树进行查找。时间复杂度为O( )到O(n)。

2、排序方法

(1)冒泡排序:通过相邻元素之间的比较和交换,使得每一趟循环都能将最大(或最小)的元素放到正确的位置。时间复杂度为O(n^2)。

(2)直接插入排序:将待排序的元素插入到已排序的序列中的适当位置,使得插入后的序列仍然有序。时间复杂度为O(n^2)。

(3)选择排序:每次从未排序的元素中找出最小(或最大)的元素,将其放到已排序序列的末尾。时间复杂度为O(n^2)。

(4)快速排序:采用分治法,将待排序的序列分为两部分,一部分是小于基准值的元素,另一部分是大于基准值的元素,然后对这两部分分别进行快速排序。时间复杂度为O(nlogn)。

(5)希尔排序:先将待排序的序列按照一定的间隔分组,对每组进行插入排序,然后逐渐减小间隔,重复上述过程,直到间隔为1,此时整个序列已经有序。时间复杂度为O(n^(3/2))。

(6)堆排序:利用堆这种数据结构,将待排序的序列构造成一个大顶堆或小顶堆,然后将堆顶元素与最后一个元素交换,再调整堆的结构,重复上述过程,直到整个序列有序。时间复杂度为O( )。

六、完整报告和成果文件提取链接

完整可运行代码以及相关实验报告以下链接可获取:
链接:https://pan.baidu.com/s/1DuGfYm6_KDm04gUKWFSSVQ?pwd=lw6u 
提取码:lw6u 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值