《数据结构与算法》实验报告
一、目的和要求(需求分析):
1、掌握数据的链式存储结构以及链表的建立和操作。
2、利用链表的原空间进行链表的反转;
(设计一个将输入数据建立成链表、并依次输出链表数据、利用原空间把链表反转的程序。)
二、程序设计的基本思想,原理和算法描述:
(包括程序的结构,数据结构,输入/输出设计,符号名说明等)
首先进行链表节点的定义,然后利用头插法创建链表,在输入数值的时候,每两个数值之间生成节点,然后依次输出原始节点。利用尾插法对链表进行就地反转,将第二个节点的next域指向第一个节点,第三个节点的next域指向第二个节点,如此,直到最后一个节点,并用head指向它。
反转链表的数据结构:
void invert(LNode* s) {
if (NULL == s){
return;
}
LNode* p = s->next;
LNode* q = p->next;
LNode* t = NULL;
p->next = NULL;
while (q != NULL) {
t = q->next;
q->next = p;
p = q;
q = t;
}
s->next = p;
}
输入数值直到遇见-1就停止输入,输出两行信息:原始链表 list data:/ 反转链表 list data:。
三、调试和运行程序过程中产生的问题及采取的措施:
在创建链表时,提示了“取消对NULL指针“p” 的引用”/ “取消对NULL指针“head” 的引用”的错误,这是因为在写代码时,没有加判断内存分配是否分配成功的语句造成的,所以要加一个if判断语句。
在输入链表值的时候,提示应该把scanf换成scanf_s。经过查询发现是因为scanf()不会检查输入边界,可能造成数据溢出。scanf_s()会进行边界检查,使原来函数更安全。
四、源程序及注释:
*
#include <stdio.h>
#include <stdlib.h>
//链表节点定义
typedef struct LNode{
int data;
struct LNode *next;
}LNode;
//创建链表
void CreateList_L(LNode *s){
LNode* p = s;
LNode *head;
int data;
while (scanf_s("%d", &data) != EOF && data != -1){
head = (LNode*)malloc(sizeof(LNode));//生成节点
if(head){
head->data = data;
head->next = NULL;
p->next = head;
p = head;
}
}
}
//打印链表数据
void display_list(LNode* s){
if (NULL == s) {
return;
}
LNode* tmp = s;
printf("list data:");
while (NULL != (tmp = tmp->next)){
printf("%d ", tmp->data);
}
printf("\n");
}
//释放链表
void free_list(LNode* s) {
if (NULL == s) {
return;
}
LNode* p = s;
while (p = p->next){
s->next = p->next;
free(p);
p = s;
}
free(s);
}
//反转链表
void invert(LNode* s) {
if (NULL == s){
return;
}
LNode* p = s->next;
LNode* q = p->next;
LNode* t = NULL;
p->next = NULL;
while (q != NULL) {
t = q->next;
q->next = p;
p = q;
q = t;
}
s->next = p;
}
int main(){
//创建链表
LNode* head;
head = (LNode*)malloc(sizeof(LNode));
CreateList_L(head);
if (NULL == head){
printf("create_list_head failed!\n");
return -1;
}
//打印原来链表数据
printf("原始链表 ");
display_list(head);
//反转链表
invert(head);
printf("反转链表 ");
display_list(head);
//释放链表空间
free_list(head);
return 0;
}
五、运行输出结果(截图与必要的文字说明):略
六、心得与体会:
通过此次实验,我掌握了数据的链式存储结构以及链表的建立和操作。学会了如何利用链表的原空间进行链表的反转。虽然上课讲的方法都能听懂,但做了实验才知道自己到底理解了多少(比如头插法、尾插法、就地反转)。写程序之前一定要画图自己把逻辑搞清楚。