一、 实验目的
1. 掌握线性表的逻辑结构;
2. 顺序表基本操作的实现;
3. 掌握利用C/C++编程语言实现数据结构的编程方法;
4. 通过上机时间加强利用数据结构解决实际应用问题的能力;
二、 实验相关知识
1. 线性表的顺序存储结构的实现;
2. 线性表的应用
三、 实验内容与要求
(一)基础题
1. 编写顺序表基本操作函数:
① InitList(LIST *L,int ms)初始化线性表;
② InsertList(LIST *L,int item,int rc)向顺序表的指定位置rc插入元素item;
③ DeleteList(LIST *L,int item)删除指定元素值item的顺序表记录;
④ DeleteList2(LIST *L,int rc)删除指定位置rc的顺序表记录;
⑤ FindList(LIST *L,int item)查找顺序表中的元素;
⑥ OutputList(LIST *L)输出顺序表元素。
2. 调用上述函数实现下列操作:
① 初始化顺序表;
② 调用插入函数建立一个顺序表;
③ 在顺序表中寻找指定的元素;
④ 在顺序表中删除指定值的元素;
⑤ 在顺序表中删除指定位置的元素;
⑥ 遍历并输出顺序表。
注:每完成一个步骤,及时地输出线性表元素,以便于观察操作结果。
list.h
#include<stdio.h>
#include<stdlib.h>
struct SeqList /*定义顺序表结构*/
{
int *list; /* 用于存储顺序表元素的数组*/
int size; /* 顺序表长度 */
int MaxSize; /* 顺序表的最大长度 */
};
typedef struct SeqList LIST;
/* 初始化线性表 */
/* L为指向顺序表的指针 */
/* ms为顺序表最大长度 */
void InitList( LIST *L, int ms );
/* 输出功能,将顺序表元素输出至控制台屏幕*/
/* L为指向顺序表的指针 */
void OutputList( LIST *L );
/* 添加功能,在顺序表的某个插入位置插入元素 */
/* 函数返回值整型,返回0成功,返回-1则失败 */
/* L为指向顺序表的指针 */
/* item为插入的元素值 */
/* rc为插入的位置(即下标) */
int InsertList( LIST *L, int item, int rc );
/* 查找功能,在顺序表中查找元素 */
/* 函数返回值整型,返回>=0 为元素位置,若返回-1则没找到 */
/* L为指向顺序表的指针,item为查找的元素 */
int FindList( LIST *L, int item );
/* 删除功能,在顺序表中删除元素 */
/* 函数返回值整型,返回>=0 为删除元素的位置,返回-1删除失败*/
/* L为指向顺序表的指针,item为删除的元素 */
int DeleteList1( LIST *L, int item );
/* 删除功能,在顺序表中删除元素 */
/* 函数返回值整型,返回0成功,返回-1删除失败 */
/* L为指向顺序表的指针,rc为删除元素的位置(即下标)*/
int DeleteList2( LIST *L, int rc );
List.cpp
void InitList( LIST *L, int ms )
{
if( (L->list = new int[] ) == NULL ) {
printf( "内存申请错误!\n" );
exit( 1 );
}
L->size = 0; /*设置初始顺序表的长度*/
L->MaxSize = ms;
}
int InsertList( LIST *L, int item, int rc )
{
int i;
if( L->size == L->MaxSize ) /* 若顺序表已满 */
return -1;
/* 合法插入位置为 0 --> L->size */
if( rc < 0 ) /* 若位置小于0,则插入位置设置为第一个元素的下标*/
rc = 0;
if( rc > L->size ) /* 若位置大于L->size,则插入位置设置为最后一个元素的后一个位置*/
rc = L->size;
for( i = L->size - 1; i >= rc; i-- ) /* 将顺序表元素后移 */
L->list[i+1] = L->list[i];
L->list[rc] = item; /*在rc位置插入item*/
L->size++; /*顺序表长度加1*/
return 0;
}
void OutputList( LIST *L ) /* 输出线性表元素 */
{
int i;
for( i = 0;i < L->size;i++ )
printf( "%d ", L->list[i]);
printf( "\n" );
}
int FindList( LIST *L, int item )
{
int i;
for( i = 0; i < L->size; i++ )
if(L->list[i] == item ) /* 找到相同的元素,返回位置 */
return i;
return -1; /* 失败 */
}
int DeleteList1( LIST *L, int item )
{
int i, n;
for( i = 0; i < L->size; i++ )
if( item == L->list[i] ) /* 找到相同的元素 */
break;
if( i < L->size ) {
for( n = i; n < L->size - 1; n++ )
L->list[n] = L->list[n+1];
L->size --;
return i;
}
return -1;
}
/* 删除指定位置的线性表记录 */
int DeleteList2( LIST *L, int rc )
{
if(rc >= L->size)
return -1;
else
for(int i = rc;i < L->size;i++)
L->list[i] = L->list[i+1];
L->size--;
return 1;
}
main.cpp
#include "List.h"
/*主函数共有7处填空,请完成*/
void main()
{
LIST LL;
int i,r;
InitList(&LL,10 ); /*初始顺序表*/
printf("list addr=%p\t size=%d\t MaxSize=%d\n",LL.list,LL.size,LL.MaxSize);/*输出初始后顺序表状态*/
while(1) /*插入元素*/
{
printf("请输入元素值,输入0结束插入操作");
fflush(stdin); /*清空标准输入缓冲区*/
scanf("%d",&i);
if( i == 0 ) /*若输入0结束*/
break;
printf("请输入插入位置:");
scanf("%d",&r);
InsertList( &LL,i,r - 1 );
printf("线性表为:");
OutputList(&LL);/*输出线性表元素*/
}
while( 1 ) /* 按元素值查找 */
{
printf( "请输入查找元素值,输入0结束查找操作:" );
fflush( stdin ); /* 清空标准输入缓冲区 */
scanf( "%d", &i );
if( i == 0 )
break;
r= FindList(&LL,i); /*按元素值查找*/
if( r < 0 )
printf( "没找到\n" );
else
printf( "有符合条件的元素,位置为:%d\n", r+1 );
}
while( 1 ) /* 按元素值删除元素 */
{
printf( "请输入删除元素值,输入0结束删除操作:" );
fflush( stdin ); /* 清空标准输入缓冲区 */
scanf( "%d", &i );
if( i == 0 )
break;
r =DeleteList1(&LL,i); /*按元素值删除*/
if( r < 0 )
printf( "没找到\n" );
else {
printf( "有符合条件的元素,位置为:%d\n线性表为:", r+1 );
OutputList( &LL );
}
}
while( 1 ) /* 按元素位置删除 */
{
printf( "请输入删除元素位置,输入0结束删除操作:" );
fflush( stdin ); /* 清空标准输入缓冲区 */
scanf( "%d", &r );
if( r == 0 )
break;
i = DeleteList2(&LL,r - 1); /*按位置删除*/
if( i < 0 )
printf( "位置越界\n" );
else {
printf( "线性表为:" );
OutputList( &LL );
}
}
system("pause");
}
(二)提高题
1. 利用顺序表表示两个一元多项式,并完成两多项式的一些运算,如加法。输入包含两行数据,第一行输入第一个一元多项式polya各项的指数和系数,且以输入0 0结束,按指数的升序创建表示第一个多项式的顺序表,第二行输入第二个一元多项式polyb各项的指数和系数,按指数的升序创建表示第二个多项式的顺序表。程序能输出两一元多项式,计算两个一元多项式和并输出,对自己的算法进行时间复杂度的分析。
【测试用例】
输入 |
3 -18 2 -49 6 13 4 -11 9 14 0 0 1 -46 3 37 4 -27 5 3 7 -123 0 0 |
输出 |
1 -46 2 -49 3 19 4 -38 5 3 6 13 7 -123 9 14 |
【解题思路】
l 一元多项式满足顺序表的逻辑结构,相邻两项具有前驱和后继的关系,故可以使用顺序表结构表示。
l 顺序表如何表示数据?
一元多项式每项都有指数和系数中,故顺序表需存储这两部分内容。改造上题中顺序表的存储结构,可参考
struct Data
{
int exp;
int coef;
};
typedef struct
{
Data *elem;
int last;
} Polylist;
l 创建多项式顺序表
初始顺序表长度为0,空表。每获取一项的指数系数则对顺序表进行插入(按指数的升序)操作。
创建好顺序表后,可以输出查看顺序表。
l 两个多项式相加
算法思相:与合并相似。两个多项式(按指数有序),将B多项式顺序表中的每一项x加入到A多项式顺序表,有以下情况:
① 若A表中不存在与x同指数的元素,则按x的指数大小插入到A表中;
② 若A表中已存在与x同指数的元素,则修改A表中与x指数相同的元素的系数应加上x的系数,若系数和为0,则要从顺序表中删除该指数对应的元素;
Poly.cpp
#include "Poly.h"
void creatPoly(Polylist *p)
{
if ((p->elem = new Data[1000]) == NULL) {
std::cout << "内存分配错误" << std::endl;
exit(1);
}
p->size = 0;
p->MaxSize = 1000;
}
void insertItem(Polylist *p, int exp, int coef)
{
Data temp;
temp.coef = coef, temp.exp = exp;
if (p->size == 0) {
p->elem[0] = temp;
p->size++;
return;
}
int index = -1;
for (int i = 0; i < p->size; i++) {
if (exp <= p->elem[i].exp) {
index = i;
break;
}
}
if (index >= 0) {
for (int i = index; i < p->size; i++) {
p->elem[i+1] = p->elem[i];
}
p->elem[index] = temp;
}
else {
p->elem[p->size] = temp; //插入线性表的最后
}
p->size++;
}
void add(Polylist *a, Polylist *b, Polylist *c)
{
int i, j;
for (i = 0, j = 0; i < a->size && j < b->size; ) {
Data t1 = a->elem[i], t2 = b->elem[j];
if (a->elem[i].exp == b->elem[j].exp) {
c->elem[c->size].exp = t1.exp;
c->elem[c->size++].coef = t1.coef + t2.coef;
i++;
j++;
} else if (a->elem[i].exp < b->elem[j].exp) {
c->elem[c->size++] = t1;
i++;
} else {
c->elem[c->size++] = t2;
j++;
}
}
while (i < a->size) {
c->elem[c->size++] = a->elem[i++];
}
while (j < b->size) {
c->elem[c->size++] = b->elem[j++];
}
}
void printPoly(Polylist *p)
{
for (int i = 0; i < p->size; i++) {
if (p->elem[i].coef > 0) std::cout << "+";
std::cout << p->elem[i].coef << "x^" << p->elem[i].exp << " ";
}
std::cout << "\n";
}
main.cpp
#include "Poly.h"
int main()
{
Polylist p1, p2,p3;
creatPoly(&p1);
printf("请输入第一个多项式的指数和系数\n");
int coef, exf;
while (std::cin >> exf >> coef) {
if (!exf && !coef) break;
insertItem(&p1, exf, coef);
}
printPoly(&p1);
printf("请输入第二个多项式的指数和系数\n");
creatPoly(&p2);
while (std::cin >> exf >> coef) {
if (!exf && !coef) break;
insertItem(&p2, exf, coef);
}
printPoly(&p2);
printf("多项式和为\n");
creatPoly(&p3);
add(&p1, &p2, &p3);
printPoly(&p3);
system("pause");
return 0;
}