您的位置:首页 > 其它

顺序表 -- 基本功能实现(仿书结构)

2011-09-17 13:36 459 查看
/*
* 题目要求:
* 按照课本第2.2节定义的线性表结构,完成对线性表结构的定义,以及对线性表的各种基本运算的实现(每种基本运算用一个函数来实现)。
* 基本运算包括:
* 初始化InitList运算、求表长Length运算、插入新节点Insert运算、删除节点Delete运算、定位(按值查找)Locate运算、读表元Get运算。
* 并且在main函数中分别调用以上各种基本运算的函数来使用,以证明其功能已实现。
* 实验效果展示可参考以下截图(也可自行设计,能展示清楚即可),此题的源程序保存为 2_a1.cpp
*/

/*
* 题目分析:
* 书上定义的线性表结构,与之前自己所习惯写的线性表定义不同点在于:
* 总体结构:它用结构体实现,没有像往常那样使用类分公有私有将其封装。
* 数据成员:只包含两个数据成员:1.定义好大小的带类型的存储向量,int[maxSize],2.包含长度int n;
* 成员函数:这次的功能并没有封装在一个类中使用成员函数实现,在使用的时候注意参数传递。
*/

#include <iostream>
#include <conio.h>        // _getch()
using std::cin;
using std::cout;
using std::endl;

// ------------------------- 顺序表数据定义 -------------------------

typedef int datatype;            // 假设顺序表结点的数据类型为整型
const int maxSize = 8;    // 设置顺序表最大长度为100
typedef struct
{
datatype elem[maxSize];        // 顺序表的存储变量
int fence;                    // 记录顺序表元素的位置
int leftSize;                // 记录顺序表的实际长度
}alist;

// ------------------------- 顺序表功能实现 -------------------------

// 初始化InitList运算
alist* InitList()
{
alist * pa = new alist;
pa -> fence = 0;
pa -> leftSize = 0;
return pa;
}

// 清空顺序表
void clearList(alist* &pa)//<---------引用
{
delete pa;
cout << "正常";
pa = NULL;//<-----------------------here
//pa = InitList(pa);
return;
}

// 判断是否为空表,满表
bool isempty(alist* pa)
{
return pa -> leftSize == 0 ? true : false;
}

bool isfull(alist *pa)
{
return pa -> leftSize == maxSize ? true : false;
}

// 检查输入需要操作顺序表中的位置是否正确(含有数据)
bool checkPos(alist* pa, int pos)
{
return (pos <= (pa -> leftSize) && pos > 0) ? true : false;
}

// 求表长Length运算
int length(alist * pa)
{
if (pa)//<-------------加个判断
return pa -> leftSize;
else
return 0;
}

// 插入新节点Insert运算
bool insert(alist* pa, datatype newElem, int position = -999)
{
// 首先判断是否表满
if ( isfull(pa) )
{
std::cerr << "\n顺序表已满,插入错误。\n";
return false;
}
// 确定是否有用户想要插入到表中的位置,若有,直接返回position,无则使用顺序中的位置fence
int pos(position == -999 ? pa -> fence : position);
// 判断是否在可插入范围内
if (pos == 1);            // 当等于1时,可以插入,跳过检查。
else if    (!checkPos(pa, pos - 1))
{
std::cerr << "\n错误的插入位置,请重新检查是否能插入。\n";
return false;
}

// 此处根据需要在顺序表中需要代入元素的次数来判断是否到达用以插入一个新元素位置。
pa -> fence = pa -> leftSize;
int j = 0;
int i = pa -> leftSize - pos + 1;
for (; j != i; ++j)
{
pa -> elem [pa -> fence] = pa -> elem[ --(pa -> fence)];
}
pa -> elem[pos - 1] = newElem;
++ (pa -> leftSize);
cout << "\n恭喜,在位置" << pos << "上,成功插入元素 " << newElem << " 。\n";
return true;
}

// 删除节点Delete运算
bool del(alist* pa, int position = -999)
{
if ( isempty(pa))
{
std::cerr << "\n此顺序表为空表,删除失败!\n";
return false;
}
// 确定是否有用户想要删除的表位置,若有,直接返回position,无则使用顺序中的位置fence
int pos(position == -999 ? pa -> fence : position);
// 判断是否在可插入范围内
if (pos == 1 || pa -> fence == pos);
else if (!checkPos(pa, pos))
{
std::cerr << "\n错误的删除位置,请重新检查是否能插入。\n";
return false;
}
// 开始删除相关操作
//加了判断,当pos==0时,pa -> elem[(pa -> fence) - 1] 导致
//elem[]的初始位置变化,delete时崩溃。
int temp;//<----------记录
if (pos==0)
{
temp = pa ->elem[pa->fence];
for ( pa -> fence = pos; pa -> fence != pa -> leftSize-1; ++(pa -> fence) )
{
pa -> elem[(pa -> fence)] = pa -> elem [pa -> fence+1];
}
-- (pa -> leftSize);
cout << "\n恭喜,在位置" << pos + 1 << "上,成功删除元素 " << temp << " 。\n";
}
else
{
temp =  pa ->elem[(pos-1 )];
for ( pa -> fence = pos; pa -> fence != pa -> leftSize; ++(pa -> fence) )
{
pa -> elem[(pa -> fence) - 1] = pa -> elem [pa -> fence];
}
-- (pa -> leftSize);
cout << "\n恭喜,在位置" << pos + 1 << "上,成功删除元素 " << temp << " 。\n";
}

return true;
}

// 读表元Get运算
datatype getElem(alist* pa, int n)
{
return  pa -> elem[n - 1];
}

// 从第n位开始遍历
void print(alist* pa, int n = 1)
{
if (pa == NULL)//<--------------here
{
return ;
}
for (pa -> fence = n - 1; pa -> fence != pa -> leftSize; ++(pa -> fence), ++n )
{
cout << getElem(pa, n) << "\t";

}
cout << endl;
return ;
}

// 定位(按值查找)Locate运算
bool findElem(alist* pa, datatype element)
{
if (isempty(pa))
{
return false;
}
for (pa -> fence = 0; pa -> fence != pa -> leftSize; ++(pa -> fence) )
{
if (element == pa -> elem[pa -> fence])
return true;
}
return false;
}

// ------------------------- 主函数 -------------------------

inline void next()
{
char a;
std::cerr << "请按任意键继续。。。";
a = _getch();
std::cerr << endl << endl;
return;
}

int main()
{
int i(0);
datatype elem(50);

cout << "———————————————— 程序测试开始 ————————————————";
// 初始化
alist* list = InitList();
cout << "\n\n\\\\ 初始化链表功能测试:\n"
<< "                       现list 表长为:" << length(list) << " " << endl << endl;
next();
cout << endl;

// 插入
cout << "\\\\ 插入功能测试:"<< endl;
// 第一个测试,测试正确插入的方法
for (i = 0; i != 6; ++i, ++elem)
{
cout << "  -尝试在第" << i + 1 << "个位置插入元素" << elem;
insert(list, elem, i + 1);
}
// 第二个测试,测试在错误位置插入的情况
cout << "  -尝试在第" << 8 << "个位置插入元素" << ++elem;
insert(list, elem, 8);
cout << "---现list 表长为:" << length(list) << " 元素:";
print(list);            // 此时已插入元素 50 - 55
next();
cout << endl;

// 寻找
cout << "\\\\ 寻找功能测试:"<< endl;
cout << " -寻找元素99";
// 第一个测试,找一些不在列表的元素
if(findElem(list, 99))
{
cout << "  寻找结果:元素在列表中。";
}
else
{
cout << "  寻找结果:元素不在列表中。";
}

// 第二个测试,找一些在列表中的元素
cout << "\n -寻找元素 " << list -> elem[0];
if(findElem(list, list -> elem[0]))
{
cout << "  寻找结果:元素在列表中。";
}
else
{
cout << "  寻找结果:元素不在列表中。";
}
cout << endl;
next();
cout << endl;

// 删除
cout << "\\\\ 删除功能测试:"<< endl;
// 第一个测试,删除刚刚查找出的元素,调用时不调用位置。
cout << "删除刚刚查找出的元素。";
del(list);
// 第二个测试,删除指定位置第三位的元素。
cout << "删除指定位置第三位的元素。";
del(list, 3);
// 第三个测试,删除错误位置第七位的元素。(现在第七位无元素)
cout << "删除错误位置第七位的元素。(现在第七位无元素)。";
del(list, 7);
// 完成功能,重新遍历
cout << "\n---现list 表长为:" << length(list) << " 元素:";
print(list);            // 此时已插入元素 50,52,54,55
next();
cout << endl;

// 清空顺序表
cout << "\\\\ 清空顺序表功能测试:"<< endl;
clearList(list);
// 完成功能,重新遍历
cout << "\n---现list 表长为:" << length(list) << " 元素:";
print(list);

cout << "\n_____________________所有的功能已经测试完毕_____________________\n";
next();
cout << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐