数据结构 实验一 顺序表 实验报告(合肥工业大学 2023级)

合肥工业大学 2023级 数据结构 实验一 完整报告

1.实验目标

  1. 掌握顺序表的基本操作。
  2. 理解顺序表的存储结构。
  3. 学会顺序表的算法设计。

2.实验要求

  1. 顺序表结构和运算定义,算法的实现以库文件方式实现,不得在测试主程序中直接实现;比如存储、算法实现放入文件:seqList.h
  2. 程序有适当的注释,程序的书写要采用缩进格式。
  3. 实验程序有较好可读性,各运算和变量的命名直观易懂,符合软件工程要求;
  4. 程序要具有一定的健壮性,即当输入数据非法时,程序也能适当地做出反应,如插入删除时指定的位置不对等等。
  5. 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
  6. 程序运行、测试正确;
  7. 根据实验报告模板详细书写实验报告。

3.实验内容

  1. 在第i个结点位置插入值为x的结点。
  2. 删除顺序表中第i个元素结点。
  3. 在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。
  4. 将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。
  5. 求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。
  6. 删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。

4.数据结构设计(所有存储结构的封装描述)

struct seqList{  
    int data[MAXLEN];  
    int listLen;  
};  

5.算法设计

1、2为书上的基本运算。

3. 在一个递增有序的顺序表L中插入一个值为x的元素,并保持其递增有序特性。

算法设计思想
  1. 声明一个顺序表L,利用指针传递给形参;
  2. 先判断顺序表存储空间是否已满;
  3. 不满时再找到比x大的元素前一个元素下标;
  4. 插入值为x的元素,顺序表长度加一;
  5. 输出运行后的顺序表。
算法描述
void zadd(seqList *L,int x){  
    int i = 0;  
    if(L->listLen == MAXLEN){  
        cout << "当前存储空间已满!" << endl;  
    }  
    else{  
        while(L->data[i] < x){       //找到比x大的元素的前一个元素下标   
            i++;  
        }  
        int k = L->listLen;  
        while(k > i){  
            L->data[k] = L->data[k-1]; //元素向后移一个位置   
            k--;  
        }  
        L->data[i] = x;                //插入元素   
        L->listLen++;                  //顺序表长度加一  
        showList(L);  
    }     
} 

4. 将顺序表L中的奇数项和偶数项结点分解开(元素值为奇数、偶数),分别放入新的顺序表中,然后原表和新表元素同时输出到屏幕上,以便对照求解结果。

算法设计思想
  1. 声明2个顺序表Q,P;
  2. 利用循环遍历L->data[i]%2是否等于0找到奇数项和偶数项;
  3. 把奇数项放入Q表中,把偶数项放入P表中;
  4. 分别输出Q、P表。
算法描述
void part(seqList *L,seqList *Q,seqList *P){  
    int j = 0,k = 0;  
    Q->listLen = 0;                       //建立空表Q   
    P->listLen = 0;                       //建立空表P   
    for(int i = 0;i < L->listLen;i++){  
        if(L->data[i]%2){                 //查找奇数项   
            Q->listLen++;  
            Q->data[j] = L->data[i];      //放入Q表中   
            j++;  
        }  
        else{  
            P->listLen++;                 //将偶数项放入P表中   
            P->data[k] = L->data[i];   
            k++;  
        }  
    }  
    cout << "奇数项";                     //输出奇数项   
    showList(Q);  
    cout << endl;  
    cout << "偶数项";                     //输出偶数项   
    showList(P);  
    cout << endl;  
}  

5. 求两个递增有序顺序表L1和L2中的公共元素,放入新的顺序表L3中。

算法设计思想
  1. 声明3个顺序表L,L1,L2,分别用指针传递给L1,L2,L3;
  2. 利用双重循环找到公共元素;
  3. 把公共元素放入空表L3中;
算法描述
void pubput(seqList *L1,seqList *L2,seqList *L3){  
    int k = 0;  
    L3->listLen = 0;                       //建立空表L3   
    for(int i = 0;i < L1->listLen;i++){       
        for(int j = 0;j < L2->listLen;j++){  
            if(L1->data[i] == L2->data[j]){ //遍历找到公共元素   
                L3->listLen++;  
                L3->data[k] = L1->data[i];  //把公共元素放入L3表中   
                k++;  
            }  
        }  
    }  
    if(L3->listLen == 0){                   //输出结果   
        cout << "没有公共元素" << endl;  
    }  
    else{  
        cout << "公共的";   
        showList(L3);  
        cout << endl;  
    }  
}  

6. 删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好。

算法设计思想
  1. 声明一个顺序表L,利用指针L传递给形参;
  2. 利用循环找到相同的元素;
  3. 从相同的第一个元素开始元素前移一个位置,i的下标不变;
  4. 计算移动次数count。
  5. 输出删除后的顺序表和移动次数。
算法描述
void delsame(seqList *L){  
    int count = 0;   
    for(int i = 0;i < L->listLen-1;i++){  
        if(L->data[i+1] == L->data[i]){     //找到相同元素   
            for(int k = i;k < L->listLen-1;k++){  
                L->data[k] = L->data[k+1];  //元素前移一个位置   
            }  
            count += L->listLen-1-i;    //计算移动次数   
            L->listLen--;               //顺序表长度减一  
            i--;                        //i的下标不变   
        }   
    }  
    cout << "删除后的";  
    showList(L);  
    cout << endl;  
    cout << "移动次数为:" << count << endl;  
}   

6.运行和测试

1.

第一组数据:顺序表长度n≥10,x=100, i分别为5,n,n+1,0,1,n+2

第二组数据:顺序表长度n=0,x=100,i=5

2.

第一组数据:顺序表长度n≥10,i分别为5,n,1,n+1,0 (以n=12为例)

第二组数据:顺序表长度n=0, i=5

3. 顺序表元素为 (10,20,30,40,50,60,70,80,90,100),x分别为25,85,110和8

4.

第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9,10,20,30,40,50,60)

第二组数据:顺序表元素为 (10,20,30,40,50,60,70,80,90,100)

5. 

第一组

第一个顺序表元素为 (1, 3, 6, 10, 15, 16, 17, 18, 19, 20)

第二个顺序表元素为 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 18, 20, 30)

第二组

第一个顺序表元素为 (1,3,6,10,15,16,17,18,19,20)

第二个顺序表元素为 (2,4,5,7,8,9,12,22)

第三组

第一个顺序表元素为 ()

第二个顺序表元素为 (1,2,3,4,5,6,7,8,9,10)

6.

第一组数据:顺序表元素为 (1,2,3,4,5,6,7,8,9)

第二组数据:顺序表元素为 (1,1,2,2,2,3,4,5,5,5,6,6,7,7,8,8,9)

第三组数据:顺序表元素为 (1,2,3,4,5,5,6,7,8,8,9,9,9,9,9)

7.总结、心得和建议

本次实验过程遇到了一个问题,对于指针的用法我还是不够了解,容易搞混弄错,在复习了指针的用法之后才完美解决这次的实验。因为此次实验内容难度较为平和,除了因为一些小错误导致改BUG花费了不少时间,本次实验过程整体比较顺利,希望自己继续努力,仔细、认真完成每一次实验,并在实验过程中发现平时学习的疏漏与不足!

附录(源代码)

seqList.h

#include <iostream>
using namespace std;
#define MAXLEN 100

struct seqList
{
    int data[MAXLEN];
    int listLen;
};
void showMenu();                                 //选                                                                                                                                                                                           择功能函数
void add(seqList *L, int x, int i); //插入函数
void del(seqList *L, int i);               //删除函数
void zadd(seqList *L, int x);              //递增插入函数
void part(seqList *L, seqList *Q, seqList *P);       //奇偶分项函数
void pubput(seqList *L1, seqList *L2, seqList *L3); //公共输出函数
void delsame(seqList *L);                        //删除重复函数

void showMenu()
{
    cout << "1、在第i个结点插入值为x的结点" << endl;
    cout << "2、删除顺序表中第i个元素节点" << endl;
    cout << "3、递增顺序表插入值为x的元素,且保持递增" << endl;
    cout << "4、分离奇偶项" << endl;
    cout << "5、两递增顺序表的公共部分" << endl;
    cout << "6、删除递增有序的重复元素,移动次数" << endl;
}
void initialList(seqList* L)
{
    L->listLen = 0;
}
void createList(seqList* L)
{
    int l = 0;
    cout << "顺序表长度:";
    cin >> l;
    int num = 0;
    cout << "请输入顺序表元素:" << endl;
    for (int i = 0; i < l; i++)
    {
        cin >> num;
        L->data[i] = num;
    }
    L->listLen += l;
}
void showList(seqList* L)
{
    for (int i = 0; i < L->listLen; i++)
    {
        cout << L->data[i] << " ";
    }
    cout << endl;
}

//1.在第i个结点位置插入值为x的结点
void add(seqList *L, int x, int i)
{
    int j = 0, k = L->listLen;
    //第二组数据测试时if条件换成
    //if(L->listlen <= 0 i < 1 || i > L->listlen+1)
    if (L->listLen < 10 || i < 1 || i > L->listLen + 1)  //判断顺序表长度是否满足条件
    {
        cout << "error" << endl;
    }
    else if (L->listLen >= MAXLEN)
    {
        cout << "存储空间已满" << endl;
    }
    else
    {
        while (j < i - 1)
        {
            j++;         //找到需要插入结点位置的数组下标
        }
        while (k > j)
        {
            L->data[k] = L->data[k - 1]; //所有元素向后移一个位置
            k--;
        }
        L->data[j] = x;      //要插入的位置赋值为X
        L->listLen++;        //顺序表长度加一
        showList(L);
    }
}
//2.删除顺序表中第i个元素结点。
void del(seqList *L, int i)
{
    int j = 0, k = L->listLen;
    int m = k;
    //第二组数据测试时if条件换成
    //if(L->listlen <= 0 || i < 1 || i > L->listlen)
    if (L->listLen < 10 || i < 1 || i > L->listLen)    //判断顺序表长度是否满足条件
    {
        cout << "error" << endl;
    }
    else
    {
        while (j < i - 1)
        {
            j++;         //找到需要插入结点位置的数组下标
        }
        while (j < L->listLen - 1)
        {
            L->data[j] = L->data[j + 1]; //元素向前移一个位置
            j++;
        }
        L->listLen--;        //顺序表长度减一
        showList(L);
    }
}
//3.在递增顺序表中插入值为X的元素,并保持递增。
void zadd(seqList *L, int x)
{
    int i = 0;
    if (L->listLen == MAXLEN)
    {
        cout << "当前存储空间已满!" << endl;
    }
    else
    {
        while (L->data[i] < x)       //找到比x大的元素的前一个元素下标
        {
            i++;
        }
        int k = L->listLen;
        while (k > i)
        {
            L->data[k] = L->data[k - 1]; //元素向后移一个位置
            k--;
        }
        L->data[i] = x;                //插入元素
        L->listLen++;                  //顺序表长度加一
        showList(L);
    }
}
//4.分开奇数项和偶数项
void part(seqList *L, seqList *Q, seqList *P)
{
    int j = 0, k = 0;
    Q->listLen = 0;                       //建立空表Q
    P->listLen = 0;                       //建立空表P
    for (int i = 0; i < L->listLen; i++)
    {
        if (L->data[i] % 2)               //查找奇数项
        {
            Q->listLen++;
            Q->data[j] = L->data[i];      //放入Q表中
            j++;
        }
        else
        {
            P->listLen++;                 //将偶数项放入P表中
            P->data[k] = L->data[i];
            k++;
        }
    }
    cout << "奇数项";                     //输出奇数项
    showList(Q);
    cout << endl;
    cout << "偶数项";                     //输出偶数项
    showList(P);
    cout << endl;
}
//5.求两个递增有序顺序表L和L2中的公共元素,放入新的顺序表L3中
void pubput(seqList *L1, seqList *L2, seqList *L3)
{
    int k = 0;
    L3->listLen = 0;                       //建立空表L3
    for (int i = 0; i < L1->listLen; i++)
    {
        for (int j = 0; j < L2->listLen; j++)
        {
            if (L1->data[i] == L2->data[j]) //遍历找到公共元素
            {
                L3->listLen++;
                L3->data[k] = L1->data[i];  //把公共元素放入L3表中
                k++;
            }
        }
    }
    if (L3->listLen == 0)                   //输出结果
    {
        cout << "没有公共元素" << endl;
    }
    else
    {
        cout << "公共的";
        showList(L3);
        cout << endl;
    }
}
//6.删除递增有序顺序表中的重复元素,并统计移动元素次数,要求时间性能最好
void delsame(seqList *L)
{
    int count = 0;
    for (int i = 0; i < L->listLen - 1; i++)
    {
        if (L->data[i + 1] == L->data[i])   //找到相同元素
        {
            for (int k = i; k < L->listLen - 1; k++)
            {
                L->data[k] = L->data[k + 1]; //元素前移一个位置
            }
            count += L->listLen - 1 - i; //计算移动次数
            L->listLen--;               //顺序表长度减一
            i--;                        //i的下标不变
        }
    }
    cout << "删除后的";
    showList(L);
    cout << endl;
    cout << "移动次数为:" << count << endl;
}

exp1顺序表实验.cpp

#include <iostream>
using namespace std;
#include "seqList.h"

int main(){
    
    while(true){
        showMenu();//显示菜单 
          seqList L;//定义一个L表 
        int choice;
        cout << "输入你的选择:";
        cin >> choice;
        int i,x,j,m;
        
        initialList(&L);//初始化链表
        createList(&L);//创建链表
        
        switch(choice){
            case 1:
                cout << "输入插入结点的位置i:";
                cin >> i;
                cout << "输入插入值x:";
                cin >> x;
                add(&L,x,i);
                break;
            case 2:		  
            	cout << "输入要删除的结点i:";
            	cin >> j;
                del(&L,j);
                break;
            case 3:
                cout << "输入在递增顺序表中要插入的x的值:";
                cin >> m;
                zadd(&L,m);
                break;
            case 4:
            	seqList A,B;
            	part(&L,&A,&B);
            	break;
            case 5:
            	seqList L2,L3;
            	initialList(&L2);
            	createList(&L2);
            	pubput(&L,&L2,&L3);
            	break;
            case 6:
            	delsame(&L);
                break;
            default:
                cout << "输入错误" << endl;
                break;
        }
   }
    
    system("pause");                          //程序结束 
    return 0;
} 	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值