数据结构实验报告-链表

   

一、实验目的

1.熟练掌握链表的结构类型定义、特点。

2.熟练掌握链表的基本操作算法的实现及其算法时间复杂度的分析。

3.掌握循环链表、双向链表的结构类型定义及其基本操作算法。掌握链表的应用。

二、实验内容

1.请编写一个完整的程序,并上机实现如下操作。

(1)产生20个1~200的随机整数,并依次保存到带头结点的单链表中。

(2)计算单链表的长度,并将结果存放在头结点的数据域中,然后输出单链表。

(3)从单链表中删除与给定值 x 相等的所有结点,然后输出单链表。

(4)在(3)题的基础上将单链表降序排列,并输出结果。

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

// 定义单链表节点结构

typedef struct Node {

    int data;

    struct Node *next;

} Node;

// 定义带头结点的单链表结构

typedef struct {

    Node *head;

} LinkList;

// 创建新节点

Node* createNode(int data) {

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

    if (!newNode) {

        exit(-1);

    }

    newNode->data = data;

    newNode->next = NULL;

    return newNode;

}

// 初始化带头结点的单链表

void initLinkList(LinkList *L) {

    L->head = createNode(0); // 创建头结点,数据域可以存长度信息

}

// 产生随机整数并保存到单链表

void generateRandom(LinkList *L) {

    srand((unsigned)time(NULL));

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

        int randomNumber = rand() % 200 + 1;

        Node *newNode = createNode(randomNumber);

        newNode->next = L->head->next; // 插入到头结点之后

        L->head->next = newNode;

    }

}

// 计算单链表的长度

int getLength(LinkList *L) {

    int length = 0;

    Node *current = L->head->next;

    while (current) {

        length++;

        current = current->next;

    }

    L->head->data = length; // 将长度存放在头结点的数据域中

    return length;

}

// 输出单链表

void printList(LinkList *L) {

    Node *current = L->head->next;

    while (current) {

        printf("%d ", current->data);

        current = current->next;

    }

    printf("\n");

}

// 删除与给定值相等的节点

void deleteWithValue(LinkList *L, int x) {

    Node *current = L->head;

    while (current->next) {

        if (current->next->data == x) {

            Node *temp = current->next;

            current->next = temp->next;

            free(temp);

        } else {

            current = current->next;

        }

    }

}

// 降序排列单链表

void sortDescending(LinkList *L) {

    Node *current = L->head->next;

    int tempData;

    while (current) {

        Node *next = current->next;

        while (next) {

            if (current->data < next->data) {

                tempData = current->data;

                current->data = next->data;

                next->data = tempData;

            }

            next = next->next;

        }

        current = current->next;

    }

}

int main() {

    LinkList L;

    initLinkList(&L);

    // (1) 产生随机整数并保存到单链表

    generateRandom(&L);

    // (2) 计算单链表的长度并输出

    printf("Length of the list: %d\n", getLength(&L));

    printList(&L);

    // (3) 删除与给定值相等的节点

    int x;

    printf("Enter the value to delete: ");

    scanf("%d", &x);

    deleteWithValue(&L, x);

    printf("List after deleting value %d:\n", x);

    printList(&L);

    // (4) 降序排列单链表并输出

    sortDescending(&L);

    printf("List after sorting in descending order:\n");

    printList(&L);

    // 释放链表内存

    Node *temp;

    while (L.head->next) {

        temp = L.head->next;

        L.head->next = temp->next;

        free(temp);

    }

    free(L.head);

    return 0;

}

  1. 用带头结点的单链表表示学生成绩表,请编写程序,完成实验1第(3)题相应的任务。

#include <stdio.h>

#include <stdlib.h> // 包含stdlib.h以使用malloc和free

// 学生结构体定义

typedef struct Student {

    int id;

    char name[50];

    float score;

} Student;

// 学生链表节点

typedef struct StudentNode {

    Student data;

    struct StudentNode *next;

} StudentNode;

// 带头结点的学生链表

typedef struct {

    StudentNode *head;

} StudentList;

// 删除指定ID的学生

void deleteStudentById(StudentList *L, int id) {

    StudentNode *current = L->head->next;

    StudentNode *prev = L->head;

    while (current) {

        if (current->data.id == id) {

            prev->next = current->next; // 跳过当前节点

            free(current); // 释放当前节点的内存

            break;

        }

        prev = current;

        current = current->next;

    }

}

int main() {

    // 初始化带头结点的学生链表

    StudentList list;

    list.head = (StudentNode*)malloc(sizeof(StudentNode)); // 分配头结点

    if (list.head == NULL) {

        exit(-1);

    }

    list.head->next = NULL; // 初始化链表为空

    // 创建一些学生节点并添加到链表中

    Student students[] = {

        {1, "Alice", 89.5},

        {2, "Bob", 92.0},

        {3, "Cathy", 78.5},

        {4, "David", 88.0},

        {5, "Ella", 91.5}

    };

    int numStudents = sizeof(students) / sizeof(students[0]);

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

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

        if (newNode == NULL) {

            exit(-1);

        }

        newNode->data = students[i];

        newNode->next = list.head->next;

        list.head->next = newNode;

    }

    // 打印原始链表

    printf("Original list:\n");

    StudentNode *current = list.head->next;

    while (current) {

        printf("ID: %d, Name: %s, Score: %.2f\n", current->data.id, current->data.name, current->data.score);

        current = current->next;

    }

    printf("\n");

    // 删除ID为3的学生

    int idToDelete = 3;

    deleteStudentById(&list, idToDelete);

    // 打印修改后的链表

    printf("List after deleting student with ID %d:\n", idToDelete);

    current = list.head->next;

    while (current) {

        printf("ID: %d, Name: %s, Score: %.2f\n", current->data.id, current->data.name, current->data.score);

        current = current->next;

    }

    printf("\n");

    // 释放链表内存

    while (list.head && list.head->next) {

        StudentNode *temp = list.head->next;

        list.head->next = temp->next;

        free(temp);

    }

    free(list.head); // 释放头结点

    return 0;

}

三、实验心得:
在本次实验中,我深入研究了链表的结构类型定义和特点。链表是一种基本的数据结构,其特点在于具有灵活的动态内存分配和插入、删除操作的高效性。通过实践操作,我熟练掌握了链表的定义和特点,对其内部指针关系有了更深入的理解。

其次,我通过实验实现了链表的基本操作算法,包括插入、删除、查找等操作,并对这些算法的时间复杂度进行了分析。我深入理解了链表操作算法的实现原理,能够准确评估算法的效率和性能。

此外,我还学习了循环链表和双向链表的结构类型定义以及基本操作算法。循环链表和双向链表在特定场景下具有优势,能够更灵活地应对实际问题的需求。通过实践操作,我掌握了这两种链表的操作方法,并能够根据需求合理选择使用哪种类型的链表。

最后,我意识到链表在实际应用中的重要性。在许多场景下,链表可以作为一种高效的数据结构,如实现栈、队列等其他数据结构,或者用于管理动态内存分配等。通过本次实验的学习,我深化了对链表的理解,提升了算法设计和实现能力,为今后在数据结构和算法领域的学习和研究奠定了坚实基础。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值