第四周作业
作业题目1:
程序运行结果截图,需测试各种情况。写出测试过程中遇到的主要问题及所采用的解决措施。
运行结果截图:
主要问题:指针的&和*用法不清楚
解决办法:多次进行调试,最终尝试得到结果
代码:
linklist.h
#pragma once
#include"function.h"
struct Node
{
int data;
struct Node* next;
};
- function.h
-
#pragma once #include<stdio.h> #include<stdlib.h> struct Node* createlist();//创建链表 void printList(struct Node* headNode);//查看链表 void insertNodeByhead(struct Node* headNode, int data);//头插 void deleteNodeByAppoin(struct Node* headNode, int posdata);//指定位置删除 int locateNode(struct Node* headNode, int data);//查找 int initList(struct Node* list);//初始化链表 void recursive_reverse(struct Node* head);//链表的就地反转
function.cpp
-
#include"linklist.h" struct Node* createlist() { struct Node* headNode = (struct Node*)malloc(sizeof(struct Node)); headNode->data = 0; headNode->next = NULL; return headNode; } struct Node* createNode(int data) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = data; newNode->next = NULL; return newNode; } void printList(struct Node* headNode) { struct Node* pMove = headNode->next; if (pMove == NULL) { printf("链表为空!"); } else { while (pMove) { printf("%d ", pMove->data); pMove = pMove->next; } } printf("\n"); } void insertNodeByhead(struct Node* headNode, int data) { struct Node* newNode = createNode(data); newNode->next = headNode->next; headNode->next = newNode; } void deleteNodeByAppoin(struct Node* headNode, int posdata) { struct Node* posNode = headNode->next; struct Node* posNodeFront = headNode; if (posNode == NULL) { printf("无法删除链表为空!\n"); } else { while (posNode->data != posdata) { posNodeFront = posNode; posNode = posNode->next; if (posNode == NULL) { printf("未找到指定元素!\n"); return; } } posNodeFront->next = posNode->next; printf("删除成功!\n"); free(posNode); } } int locateNode(struct Node* headNode, int data) { struct Node* p = headNode->next; int i=1; while (p->next!=NULL) { if (p->data != data) { i++; p = p->next; } else { return i; } } printf("没有找到数据\n"); return -1; } int initList(struct Node* list) { struct Node* p; struct Node* q; p = list->next; while (p) { q = p->next; free(p); p = q; } list->next = NULL; return 1; } void recursive_reverse(struct Node* head) { if (head->next == NULL) return; struct Node* pre = NULL; struct Node* cur = head->next; struct Node* next; while (cur) { next = cur->next; cur->next = pre; pre = cur; cur = next; } head->next = pre; }
linklist.cpp
-
#include"linklist.h" void menu() { printf("[1]创建链表\n"); printf("[2]头插元素\n"); printf("[3]查看链表\n"); printf("[4]删除元素\n"); printf("[5]查找元素\n"); printf("[6]清空链表\n"); } int main() { struct Node* list = createlist(); menu(); printf("请输入操作\n"); while (1) { int choose = 0; int item = 0; int del = 0; int loc = 0; scanf_s("%d", &choose); switch (choose) { case 1: { struct Node* list = createlist(); printf("链表创建成功!\n"); printf("\n请输入操作\n"); break; } case 2: { printf("请分别输入数据,且以-1结尾\n"); while (1) { scanf_s("%d", &item); if (item == -1) { break; } insertNodeByhead(list, item); } recursive_reverse(list); printf("\n请输入操作\n"); break; } case 3: { printf("链表元素如下:\n"); printList(list); printf("\n请输入操作\n"); break; } case 4: { printf("请输入要删除的元素:\n"); scanf_s("%d", &del); deleteNodeByAppoin(list, del); printf("\n请输入操作\n"); break; } case 5: { printf("请输入要查找的元素:\n"); scanf_s("%d", &loc); if (locateNode(list, loc)) printf("所查找元素的位置为:%d\n", locateNode(list, loc)); else printf("您查找的数值不存在。\n"); printf("\n请输入操作\n"); break; } case 6: { initList(list); printf("清空成功!\n"); printf("\n请输入操作\n"); } } } system("pause"); return 0; }
作业题目2:
1.题目描述:
假设有一个带头结点的单链表L={a1,b1,a2,b2,…,an,bn}。设计一个算法将其拆分成两个带头结点的单链表L1和L2:L1={a1,a2,…,an},L2={bn,bn-1,…,b1},要求L1使用L的头结点。
2.问题分析:
(1)程序的功能要求;把链表拆分并反向
(2)程序的界面设计:分别为:请输入链表中的元素个数,请输入链表中的元素,链表L1中的元素为,链表L2中的元素为
(3)程序的错误处理:当输入链表的个数为0时,直接输出为空;当输入链表的个数为奇数是,则L2中默认少一位
3.方案设计
1.数据类型设计:
typedef struct Node
{
int elem;
struct Node* next;
}*linklist;
2.算法设计(算法的基本思想、具体步骤,各程序模块之间的层次(调用)关系流程图等):
用函数的方式模块化完成任务,并且界面简洁,功能清晰
4.测试分析
设计测试范例(测试数据包括正确的输入、边界条件、含有错误的输入等),列出程序的测试结果(附截图),测试结果的分析与讨论。可列出测试过程中遇到的主要问题及所采用的解决措施。
5.心得
对实验设计与实现过程的回顾和分析,说明程序的改进思想、经验和体会。
实验设计中,只要思路清晰,写代码就变的清晰和容易
函数注释要写清晰,不然可能会误导自己和其他看代码的人
多文件系统使代码变得更简洁
6.附录
列出程序文件清单,及文件功能。
头文件:
linklist.h:放函数基本头文件,结构类型定义,函数声明等
源文件:
linklist.cpp:放主函数的操作
function.cpp:放函数的代码
代码注释要求:
- 对关键的算法实现代码有必要的注释
- 函数说明格式:
*****************************************************
函数名:
函数功能:
输入参数:
类型,参数名,含义
输出参数:
返回值,含义
文件提交要求:
将两道题目各自的完整工程(包含该工程下所有目录和文件)和此文档一起打包,以组内学生姓名作为文件名,上传提交。例如Stu1_Stu2.zip
linklist.h
#pragma once
# include <iostream>
# include <stdlib.h>
# include <stdio.h>
using namespace std;
typedef struct Node
{
int elem;
struct Node* next;
}*linklist;
void inlinklist(linklist& l, int n);
/********************************
函数名:inlinklist
函数功能:输入链表的值
输入参数:类型,参数名,含义
linklist,l,链表
int,l,输入的元素个数
输出参数:返回值,含义
void,为空
*********************************/
void outlinklist(linklist l);
/********************************
函数名:outlinklist
函数功能:输出链表的值
输入参数:类型,参数名,含义
linklist,l,链表
输出参数:返回值,含义
void,为空
*********************************/
void splitlinklist(linklist& l1, linklist& l2, linklist& l3);
/********************************
函数名:splitlinklist
函数功能:把链表分开
输入参数:类型,参数名,含义
linklist,l1 l2 l3,第一链表 第二链表 第三链表
输出参数:返回值,含义
void,为空
*********************************/
void recursive_reverse(struct Node* head);
/********************************
函数名:recursive_reverse
函数功能:链表的就地反转
输入参数:类型,参数名,含义
struct Node,head,链表
输出参数:返回值,含义
void,为空
*********************************/
function.cpp
#include"linklist.h"
void inlinklist(linklist& l, int n)
{
l = (linklist)malloc(sizeof(Node));
l->next = NULL;
linklist p, end;
end = l;
printf("请输入链表中的元素:\n");
for (int i = 0; i < n; i++)
{
p = (linklist)malloc(sizeof(Node));
scanf("%d", &p->elem);
end->next = p;
p->next = NULL;
end = p;
}
}
void outlinklist(linklist l)
{
linklist p;
p = l->next;
while (p)
{
printf("%d ", p->elem);
p = p->next;
}
printf("\n");
}
void splitlinklist(linklist& l1, linklist& l2, linklist& l3)
{
l2 = (linklist)malloc(sizeof(Node));
l3 = (linklist)malloc(sizeof(Node));
linklist p, q, s;
p = l1->next;
q = l2;
s = l3;
int j = 1;
while (p)
{
if (j % 2 != 0)
{
q->next = p;
q = q->next;
}
else
{
s->next = p;
s = s->next;
}
j++;
p = p->next;
}
q->next = NULL;
s->next = NULL;
}
void recursive_reverse(struct Node* head)
{
if (head->next == NULL) return;
struct Node* pre = NULL;
struct Node* cur = head->next;
struct Node* next;
while (cur) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
head->next = pre;
}
linklist.cpp
#include"linklist.h"
int main()
{
linklist l1, l2, l3;
int n;
printf("请输入链表中的元素个数:\n");
scanf_s("%d", &n);
inlinklist(l1, n);
splitlinklist(l1, l2, l3);
printf("链表L1中的元素为:\n");
outlinklist(l2);
recursive_reverse(l3);
printf("链表L2中的元素为:\n");
outlinklist(l3);
return 0;
}