实验2.1 线性表的应用:最小差值
[问题描述]
必须利用实验一实现的线性表ADT,完成下面的题目。
对于给定n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值。
[输入形式]
输入第一行包含一个整数n。
第二行包含n个正整数,相邻整数之间使用一个空格分隔。
[输出形式]
输出一个整数,表示答案。
问题分析
要处理的对象(数据):
通过键盘输入的一组整数,以数组的形式,存储到计算机中
要实现的功能:
先接收一个键盘输入的代表该组整数个数的数字,再依次接收该组整数
处理后的结果如何显示:
将得到的最小差值输出在屏幕上
输入样例
【求解方法】
将该组整数放入数组,利用双重循环,计算数组中每个整数与其他整数的差值的
绝对值,用一个整数记录最小差值
【样例求解过程一】
1.输入一组整数: 1 5 4 8 20
2.整数存入数组: a[5]={1,5,4,8,20}
3.利用外循环循环遍历数组:
再利用内循环计算每一个整数与该整数后面数的差值的绝对值
|1-5|=4 min=4 |1-4|=3 min=3 |1-8|=7 min=3 |1-20|=19 min=19
|5-4|=1 min=1 |5-8|=3 min=1 |5-20|=15 min=1
|4-8|=4 min=1 |4-20|=16 min=1
|8-20|=12 min=1
4.输出最小差值 1
【样例求解过程二】
1.输入一组整数: 9 3 6 1 3
2.整数存入数组: a[5]={9,3,6,1,3}
3.利用外循环循环遍历数组:
再利用内循环计算每一个整数与该整数后面数的差值的绝对值
|9-3|=6 min=6 |9-6|=3 min=3 |9-1|=7 min=3 |9-3|=6 min=3
|3-6|=3 min=3 |3-1|=2 min=2 |3-3|=0 min=0
|6-1|=5 min=0 |6-3|=3 min=0
|1-3|=2 min=0
4.输出最小差值 0
抽象数据类型设计
数据对象: 一组整数
数据关系: 从键盘输入一个代表该组整数个数的数字后换行,再输入一组整数,
以换行符结束输入,按照输入的先后次序,满足线性特征
【线性表ADT的表示】
ADT IntegerSet{
数据对象: D = {ai | ai ∈ 整数 ,i = 1 ,2 , ···, n, n>=0}
数据关系: R = {<ai ,ai+1> | ai-1 ,ai ∈ D}
基本操作:
AList(int size) // 操作功能:构造函数,创建线性表
void clear() // 操作功能:清空线性表
void append(const E& it) // 操作功能: 插入“it”到链表尾
int currPos() // 操作功能: 返回当前元素的位置
void moveToPos(int pos) // 操作功能: 向下移动到链表“pos”位置
const E& getValue() // 操作功能: 返回当前元素
}
物理数据对象设计
物理存储方式: 整型
算法思想的设计:
准备一个能够存储一组整数的存储空间。
利用双重循环,计算数组中每个整数与其他整数的差值的绝对值,输出最小值
关键功能的算法步骤:
计算数组中每个整数与其他整数的差值的绝对值:
for(int i=0;i<n;i++)
{
L1.moveToPos(i); // 设置当前位置为i
int a=L1.getValue(); // 得到位置为i的元素的值
for (int j=i+1;j<n;j++)
{
L1.moveToPos(j); // 设置当前位置为j
int b=L1.getValue(); // 得到位置为j的元素的值
int c=b-a;
if(c<0) c=-c; //计算数组中每个整数与其他整数的差值的绝对值
if(j==1) min=c; //第一个设为最小值的第一个
else if(c<min) min=c; //其他用于比较最小值
}
}
时间复杂度为: O(n平方)
空间复杂度为: θ(n)
实验代码
【线性表的声明】
#ifndef LIST
#define LIST
template <typename E> class List { //线性表的声明
private:
void operator =(const List&) {}
List(const List&) {}
public:
List() {} //默认构造函数
virtual ~List() {} //析构函数
virtual void clear() = 0; //清除列表中的内容,使其为空
//插入元素
virtual void append(const E& item) = 0;
//返回当前元素。
virtual const E& getValue() const = 0;
//设置当前位置。
// pos:当前位置。
virtual void moveToPos(int pos) = 0;
};
#endif
【基于数组的顺序表实现】
#include "list.h"
#include <assert.h>
template <typename E> //基于数组的顺序表实现
class AList : public List<E> {
private:
int maxSize; //表的最大大小
int listSize; //现在列表项的数量
int curr; //当前元素位置位置
E* listArray; //保留列表元素的数组
public:
//构造函数
AList(int size = 100) {
maxSize = size;
listSize = curr = 0;
listArray = new E[maxSize];
}
~AList() { delete[] listArray; } //析构函数
void clear() { //清除列表中的内容,使其为空
delete[] listArray; //删除数组
listSize = curr = 0; //重置大小
listArray = new E[maxSize]; //创建数组
}
//插入元素
void append(const E& it) {
assert(listSize < maxSize);
listArray[listSize++] = it;
}
//设置当前位置。
void moveToPos(int pos)
{
assert((pos >= 0) && (pos <= listSize));
curr = pos;
}
//返回当前元素。
const E& getValue() const
{
assert((curr >= 0) && (curr < listSize));
return listArray[curr];
}
};
【主函数】
#include "list.h"
#include "alist.h"
#include <iostream>
using namespace std;
int main() {
int n,min=0,s; //设置数组的大小,最小差值
cin>>n;
AList<int> L1(n); //创建顺序表
for(int i=0;i<n;i++)
{
cin>>s;
L1.append(s); //调用顺序表中的插入操作
}
for(int i=0;i<n;i++)
{
L1.moveToPos(i);
int a=L1.getValue();
for (int j=i+1;j<n;j++)
{
L1.moveToPos(j);
int b=L1.getValue();
int c=b-a;
if(c<0) c=-c;
if(j==1) min=c;
else if(c<min) min=c;
}
}
cout<<min;
L1.clear();
return 0;
}