首页 > 其他分享 >数据结构实验一

数据结构实验一

时间:2025-01-10 16:56:58浏览次数:1  
标签:Node head return int next 链表 实验 数据结构

石 家 庄 铁 道 大 学
实 验 报 告

课程名称: 数据结构与算法设计 任课教师: 刘 丹 实验日期: 2024.12.11
班 级: 信2305-3 姓 名: 徐戌 学 号: 20234316

实验项目名称:实验一
一、 实验目的
掌握顺序表的基本操作。
掌握单链表的基本操作。
掌握循环链表的基本操作。

二、 实验内容

三、 设计文档

四、 源程序
链表逆置:

include <stdio.h>

include <stdlib.h>

struct ListNode {
int data;
struct ListNode *next;
};

struct ListNode createlist(); /裁判实现,细节不表*/
struct ListNode *reverse( struct ListNode *head );
void printlist( struct ListNode *head )
{
struct ListNode *p = head;
while (p) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}

int main()
{
struct ListNode *head;

head = createlist();
head = reverse(head);
printlist(head);

return 0;

}
struct ListNode* reverse(struct ListNode* head)
{
struct ListNode* q = head, * t, * p = NULL;
while (q)
{
t = q->next;
q->next = p;
p = q; 9
q = t;
}
return p; }
7-1 线性表A,B顺序存储合并

include <stdio.h>

include <stdlib.h>

void mergeAndRemoveDuplicates(int *A, int lenA, int *B, int lenB) {
int *C = (int *)malloc((lenA + lenB) * sizeof(int)); // 合并后的数组
int i = lenA - 1, j = lenB - 1, k = 0; // i, j分别为A和B的指针,k为C的指针

// 合并A和B到C,C要保持非递减顺序
while (i >= 0 && j >= 0) {
    if (A[i] < B[j]) {
        C[k++] = A[i--];
    } else {
        C[k++] = B[j--];
    }
}

// 如果A还有剩余元素
while (i >= 0) {
    C[k++] = A[i--];
}

// 如果B还有剩余元素
while (j >= 0) {
    C[k++] = B[j--];
}

// 去重:将去重后的元素存回C,并打印结果
int last = C[0];
printf("%d", last); // 第一个元素先输出

for (int i = 1; i < k; i++) {
    if (C[i] != last) {
        printf(",%d", C[i]);
        last = C[i];
    }
}
free(C); // 释放内存

}

int main() {
int A[100], B[100];
int lenA = 0, lenB = 0;

// 输入表A
while (1) {
    scanf("%d", &A[lenA]);
    if (A[lenA] == -1) break;
    lenA++;
}

// 输入表B
while (1) {
    scanf("%d", &B[lenB]);
    if (B[lenB] == -1) break;
    lenB++;
}

mergeAndRemoveDuplicates(A, lenA, B, lenB);

return 0;

}
7-2 双向循环链表应用

include <stdio.h>

include <stdlib.h>

// 双向循环链表结点结构
typedef struct Node {
int data;
struct Node* prior; // 指向前驱节点
struct Node* next; // 指向后继节点
} Node;

// 创建一个新的结点
Node* create_node(int data) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = data;
new_node->prior = new_node->next = new_node; // 初始化为自己指向自己(循环链表)
return new_node;
}

// 创建双向循环链表
Node* create_list(int arr[], int n) {
if (n == 0) return NULL;

Node* head = create_node(arr[0]);
Node* tail = head;

for (int i = 1; i < n; i++) {
    Node* new_node = create_node(arr[i]);
    tail->next = new_node;
    new_node->prior = tail;
    tail = new_node;
}
// 最后一个节点的next指向头结点,头结点的prior指向最后一个节点
tail->next = head;
head->prior = tail;

return head;

}

// 在双向循环链表中查找指定值的结点
Node* find_node(Node* head, int value) {
Node* current = head;
if (head == NULL) return NULL;
do {
if (current->data == value) return current;
current = current->next;
} while (current != head);
return NULL;
}

// 交换p指向结点和它的前驱结点
void swap_nodes(Node* p) {
if (p == NULL || p->prior == p) return; // 如果p是链表的头结点或链表只有一个结点,无法交换

Node* prev = p->prior;
Node* next = p->next;

// 调整前驱节点的next和p的prior指向
prev->next = p->next;
p->prior = prev->prior;

// 调整p的next和后继节点的prior指向
p->next = prev;
prev->prior = p;

// 如果p是链表的头结点,需要更新头结点的prior指向p
if (p->prior != NULL) {
    p->prior->next = p;
}
if (next != NULL) {
    next->prior = prev;
}

}

// 输出链表
void print_list(Node* head) {
if (head == NULL) return;
Node* current = head;
do {
printf("%d", current->data);
current = current->next;
} while (current != head);
printf("\n");
}

int main() {
int N;
scanf("%d", &N);
if (N <= 0) {
printf("error\n");
return 0;
}

int arr[N];
for (int i = 0; i < N; i++) {
            if (scanf("%d", &arr[i]) != 1) {
        printf("error\n");
        return 0;
    }
}

int value_to_swap;
scanf("%d", &value_to_swap);

// 创建双向循环链表
Node* head = create_list(arr, N);

// 查找目标结点
Node* p = find_node(head, value_to_swap);
if (p == NULL) {
    printf("未找到%d\n", value_to_swap);
} else {
    // 交换p与它的前驱结点
    swap_nodes(p);
    // 输出修改后的链表
    print_list(head);
}

return 0;

}
7-3 修改数组(蓝桥杯)

include <stdio.h>

include <stdlib.h>

define MAX_VAL 1000000

// 使用一个简单的哈希表来检查是否有重复的元素
typedef struct HashSet {
int *data;
} HashSet;

// 创建一个哈希表
HashSet* create_hashset(int size) {
HashSet* set = (HashSet)malloc(sizeof(HashSet));
set->data = (int
)calloc(size, sizeof(int)); // 使用 calloc 初始化为 0
return set;
}

// 向哈希表中插入一个元素
void insert(HashSet* set, int value) {
set->data[value] = 1;
}

// 检查哈希表中是否存在该元素
int contains(HashSet* set, int value) {
return set->data[value] == 1;
}

// 释放哈希表的内存
void free_hashset(HashSet* set) {
free(set->data);
free(set);
}

int main() {
int N;

// 输入 N
if (scanf("%d", &N) != 1 || N < 1 || N > 100000) {
    printf("error\n");
    return 0;
}

int A[N];
// 输入数组 A
for (int i = 0; i < N; i++) {
    if (scanf("%d", &A[i]) != 1 || A[i] < 1 || A[i] > 1000000) {
        printf("error\n");
        return 0;
    }
}

HashSet* set = create_hashset(MAX_VAL + 1);  // 创建哈希表

for (int i = 0; i < N; i++) {
    while (contains(set, A[i])) {  // 如果当前值已经存在
        A[i]++;  // 增加该元素的值
    }
    insert(set, A[i]);  // 将当前修改后的元素插入哈希表
}

// 输出最终的数组
for (int i = 0; i < N; i++) {
    printf("%d ", A[i]);
}
printf("\n");

// 释放哈希表
free_hashset(set);

return 0;

}
五、 个人体会
链表逆置是一个常见的数据结构操作,通常用于改变链表中节点的顺序。在实现链表逆置的过程中,我遇到一些问题,比如说链表的头节点弄错了位置应该是从尾到头,而我刚开始设计实验的时候是从到尾以至于我刚开始不会做,我采取了一些列措施比如说循环倒序,使得数字能够从小到大排序。还有就是链表储存问题:内存分配失败,在扩容过程中,内存不足,导致内存分配失败。解决方案:在尝试分配新内存之前,先检查系统是否有足够的可用内存。如果内存不足,可以尝试释放一些不再使用的内存,或者抛出异常并处理。
实验感想:通过这次链表实验,我对链表这一数据结构有了更深入的理解。实验中,我实现了链表的基本操作,如插入、删除、查找和逆置等,这不仅巩固了理论知识,还提高了实际编程能力。特别是在调试过程中,我遇到了指针错误和内存泄漏等问题,通过逐步排查和修复,我学会了如何更有效地解决问题。此外,实验还让我认识到数据结构选择的重要性,不同的应用场景需要不同的数据结构来优化性能。总体来说,这次实验不仅提升了我的编程技能,也增强了我对算法和数据结构的兴趣和信心。

标签:Node,head,return,int,next,链表,实验,数据结构
From: https://www.cnblogs.com/-Xuxu/p/18664242

相关文章

  • 数据结构实验2
    7-2双向循环链表应用已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,实现交换p所指向的结点和它的前缀结点的顺序。输入格式:第一行输入元素个数,第二行输入元素值,第三行输入要交换的元素值,第四行输出结果。输出格式:输出交换后的结果,中间不用空格分......
  • 数据结构实验三
    石家庄铁道大学实验报告课程名称:信2305-3 任课教师:刘丹 实验日期:2024.12.15班级:信2305-3 姓名:徐戌 学号:20234316实验项目名称:实验三一、 实验目的1.掌握二叉树的定......
  • 数据结构实验五
    石家庄铁道大学实验报告课程名称:数据结构与算法设计 任课教师:刘丹 实验日期:2024.12.15班级:信2305-3 姓名:徐戌 学号:20234316实验项目名称:实验五一、 实验目的1.掌握散列表......
  • 数据结构实验3
    7-3修改数组(蓝桥杯)给定一个长度为N的数组A=[A1,A2,⋅⋅⋅AN],数组中有可能有重复出现的整数。现在小明要按以下方法将其修改为没有重复整数的数组。小明会依次修改A2,A3,⋅⋅⋅,AN。当修改Ai时,小明会检查Ai是否在A1∼Ai−1中出现过。如果出现过,则小明会给Ai加上......
  • 数据结构实验四
    石家庄铁道大学实验报告课程名称:信2305-3 任课教师:刘丹 实验日期:2024.12.15班级:信2305-3 姓名:徐戌 学号:20234316实验项目名称:实验四一、 实验目的1)掌握图的邻接矩......
  • 数据结构实验4
    7-2栈实现表达式求值使用键盘输入数学表达式(含数字,四种运算符+、-、、/和小括号,其中运算数都是一位数(0~9)),将数学表达式转化成后缀表达式输出,利用后缀表达式求表达式的值并输出。输入格式:输入正确的表达式(可以有空格)后回车,得到后缀表达式和结果。输入括号缺失的表达式,输出"ERR......
  • 数据结构实验六
    石家庄铁道大学实验报告课程名称:数据结构与算法设计 任课教师:刘丹 实验日期:2024.12.15班级:信2305-3 姓名:徐戌 学号:20234316实验项目名称:实验六一、 实验目的1.掌握插入排......
  • 【西南科技大学计算机学院、智能计算与系统结构实验室主办 | ACM独立出版 | 往届均已
    ACM独立出版|往届均已成功检索,最快刊后1个月内实现EI检索征稿主题范围广:计算机网络安全、软件工程、信号处理、程序分析等领域主办单位:西南科技大学计算机学院、智能计算与系统结构实验室第五届计算机网络安全与软件工程国际学术会议(CNSSE2025)20255thInternational......
  • 数据结构(红黑树)
    问题的起源学习一个知识模块,一般先要厘清学习的目的,一个技术分支的出现必然是应对某个具体问题而产生的解决方案,搞清楚了问题的起源,对解决问题的思路就有了根本性的理解,来龙去脉把握清楚了学习起来就既有动力又有目标了。回归到红黑树的问题,红黑树其实也是一种平衡树,之前......
  • JSP开放实验室预约管理系统2118f--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景与意义随着教育和科研的不断发展,实验室资源的有效管理和开放共享成为重要议题。传统的人工管理方式存在效率低、资源浪费等问题,无法满......