线性表的基本操作及其应用

线性表的基本操作及其应用

一、实验目的

1、帮助读者复习C++语言程序设计中的知识。

2、熟悉线性表的逻辑结构。

3、熟悉线性表的基本运算在两种存储结构上的实现,其中以熟悉链表的操作为侧重点。

 

二、实验内容

本次实验提供4个题目,每个题目都标有难度系数,*越多难度越大,学生可以根据自己的情况选做!

题目一:单链表的基本操作(*)

[问题描述]

实现带头结点的单链表的建立、求长度,取元素、修改元素、插入、删除等单链表的基本操作。

[基本要求]

(1)依次从键盘读入数据,建立带头结点的单链表;

(2)输出单链表中的数据元素

(3)求单链表的长度;

(4)根据指定条件能够取元素和修改元素;

(5)实现在指定位置插入和删除元素的功能。

 [测试数据]

由学生任意指定。

 

1总体设计

 

 

 

节点

依次从键盘读入数据,建立带头结点的单链表

输出单链表中的元素

求单链表的长度

 

指定位置

/

修改元素

指定位置删除/

插入元素

单链表

 

 

 

 

 

 

 

 

 

 

 

 

 


2、详细设计及重要代码:

voidCreateList_L(LinkList &L)   

{//依次从键盘读入数据,建立带头结点的单链表

  int i,n;

  LNode *p;

  L=(LinkList)malloc(sizeof(LNode));

  L->next=NULL;

  cout<<"请输入元素个数:"<<endl;

  cin>>n;

  cout<<"请输入待插入链表的数据:(例如: 34,67,3,-9,45,...)"<<endl;

  for(i=n;i>0;--i)

  {

        p=(LinkList)malloc(sizeof(LNode));

        cin>>p->data;                           

        p->next=L->next;

        L->next=p;

  }

}

voidInsretdataList_L(LinkList &L)

{//指定位置插入元素

       LNode *p;

       int j=0;

       p=L;

       int i;

       cout<<"请输入指定位置:"<<endl;

       cin>>i;

       while(p&&j<i-1)

       {

              p=p->next;++j;

       }

       if(!p||j>i-1)

       {

              cout<<"第"<<i<<"数据不存在!"<<endl;

              return;  

       }

       int e;

       cout<<"请输入待插入的元素:"<<endl;

       cin>>e;

       LNode *s;

    s=new LNode[sizeof(LNode)];    //创建一个新节点

    s->data=e;

    s->next=p->next;

    p->next=s;

}

 

voidDeletedataList_L(LinkList &L)

{//指定位置删除元素

       LNode *p,*q;

       int j=0;

       p=L;

       int i;

       cout<<"请输入指定位置:"<<endl;

       cin>>i;

       while(p&&j<i-1)

       {

              p=p->next;++j;

       }

       if(!p||j>i-1)

       {

              cout<<"第"<<i<<"数据不存在!"<<endl;

              return;  

       }

       q=p->next;

       p->next=q->next;                 

       free(q);

}

3、功能截图展示:


输出:


插入元素:


4、程序清单

#include<stdio.h>
#include<iostream>
usingnamespace std;
 
typedefstruct LNode
{      int data;
       struct LNode *next;
}LNode,*LinkList;
 
voidCreateList_L(LinkList &L)   
{//依次从键盘读入数据,建立带头结点的单链表
  int i,n;
  LNode *p;
  L=(LinkList)malloc(sizeof(LNode));
  L->next=NULL;
  cout<<"请输入元素个数:"<<endl;
  cin>>n;
  cout<<"请输入待插入链表的数据:(例如: 34,67,3,-9,45,...)"<<endl;
  for(i=n;i>0;--i)
  {
        p=(LinkList)malloc(sizeof(LNode));
        cin>>p->data;                           
        p->next=L->next;
        L->next=p;
  }
}
 
voidPrintfList_L(LinkList &L)
{//输出单链表中的元素
       LNode *p;
       p=L->next;
       while(p)
       {
              cout<<p->data<<"";
              p=p->next;
       }
       cout<<endl;
}
 
voidGetlendthList_L(LinkList &L)
{//求单链表的长度
       int i=0;
       LNode *p;
       p=L->next;
       while(p)
       {
              ++i;
              p=p->next;
       }
       cout<<"该单链表元素个数位:"<<i<<endl;
}
 
voidGetdataList_L(LinkList &L)
{//指定位置取元素
       LNode *p;
       int j=1;
       p=L->next;int i;
       cout<<"请输入指定位置:"<<endl;
       cin>>i;
       while(p&&j<i)
       {
              p=p->next;++j;
       }
       if(!p||j>i)
       {
              cout<<"第"<<i<<"数据不存在!"<<endl;
              return;  
       }
       cout<<"第"<<i<<"个位置的元素是:"<<p->data<<endl;
}
 
voidModifydataList_L(LinkList &L)
{//指定位置修改元素
       LNode *p;
       int j=1;
       p=L->next;
       int i;
       cout<<"请输入指定位置:"<<endl;
       cin>>i;
       while(p&&j<i)
       {
              p=p->next;++j;
       }
       if(!p||j>i)
       {
              cout<<"第"<<i<<"数据不存在!"<<endl;
              return;  
       }
       cout<<"请输入修改后的元素:"<<endl;
       cin>>p->data;
}
 
voidInsretdataList_L(LinkList &L)
{//指定位置插入元素
       LNode *p;
       int j=0;
       p=L;
       int i;
       cout<<"请输入指定位置:"<<endl;
       cin>>i;
       while(p&&j<i-1)
       {
              p=p->next;++j;
       }
       if(!p||j>i-1)
       {
              cout<<"第"<<i<<"数据不存在!"<<endl;
              return;  
       }
       int e;
       cout<<"请输入待插入的元素:"<<endl;
       cin>>e;
       LNode *s;
    s=new LNode[sizeof(LNode)];    //创建一个新节点
    s->data=e;
    s->next=p->next;
    p->next=s;
}
 
voidDeletedataList_L(LinkList &L)
{//指定位置删除元素
       LNode *p,*q;
       int j=0;
       p=L;
       int i;
       cout<<"请输入指定位置:"<<endl;
       cin>>i;
       while(p&&j<i-1)
       {
              p=p->next;++j;
       }
       if(!p||j>i-1)
       {
              cout<<"第"<<i<<"数据不存在!"<<endl;
              return;  
       }
       q=p->next;
       p->next=q->next;                 
       free(q);
}
 
intmain()
{
       LinkList L;
       LNode *p;
       int e;
       char a;
       int i,j,n=1;                                                
       int LListNodeNum;
       while(n!=8)
       {
              system("cls");
              cout<<"======================================="<<endl;
              cout<<"=========单链表的基本操作=============="<<endl;
              cout<<"======================================="<<endl;
              cout<<"--------1、创建单链表------------------"<<endl;
              cout<<"--------2、输出单链表所有元素----------"<<endl;
              cout<<"--------3、获取单链表长度--------------"<<endl;
              cout<<"--------4、指定位置取元素--------------"<<endl;
              cout<<"--------5、指定位置修改元素------------"<<endl;
              cout<<"--------6、指定位置插入元素------------"<<endl;
              cout<<"--------7、指定位置删除元素------------"<<endl;
              cout<<"======================================="<<endl;
skip:       cout<<"请选择功能:"<<endl;
              cin>>n;
              switch(n)
              {
              case 1:CreateList_L(L);break;
              case 2:PrintfList_L(L);break;
              case 3:GetlendthList_L(L);break;
              case 4:GetdataList_L(L);break;
              case 5:ModifydataList_L(L);break;
              case 6:InsretdataList_L(L);break;
              case 7:DeletedataList_L(L);break;
              degault:goto skip;
              }
skip1:            cout<<"是否退出:(Y/N或y/n)"<<endl;
              cin>>a;
              if(a=='y'||a=='Y')
                     break;
              else if(a=='n'||a=='N')continue;
              else
              {cout<<"输入有误,请重新输入!"<<endl;
              goto skip1;
              }
              return 0;
       }
}


 

题目二:约瑟夫环(**)

 [问题描述]
约瑟夫(Joseph)问题的一种描述是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。试设计一个程序求出出列顺序。

[基本要求]
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
[测试数据]

由学生任意指定。
  如:m的初值为20;n的值为7;密码:3,1,7,2,4,8,4;

(正确的输出结果应为6,1,4,7,2,3,5)。
    (
报告上要求写出多批数据测试结果)
[实现提示]
程序运行后首先要求用户输入初始报数上限值m,人数n,(设n≤30)。然后输入各人的密码。

[选作内容]
向上述程序中添加在顺序结构上实现的部分。

 

1、总体设计(设计思想)

构造一个单向循环链表,每一个节点即代表一个人,因为最后要求的是输出出列的顺序印出各人的编号,所以在创建链表的时候给节点结构体多加一个参数(属性)来记录每个人的编号。

2、详细设计及重要代码:

本题的重点就就构建单向循环链表,只要把这个弄好了,我的思路是先创建一个节点,让它的next指针指向自己,然后向它后面插入节点,插入的节点的next指针一直指向字一个节点,这样就构成了地啊想循环链表

3、功能截图展示:

  

4、程序清单

#include<iostream>
usingnamespace std;
typedefstruct LNode
{
       int num;
       int code;
       struct LNode *next;
}LNode,*Link;
voidInitList(Link &L)    //初始化循环链表
{
       L = new LNode;
       L->next = L;
}
voidLeave(Link &L, int n, int m)
{
       if (!L)
       {
              cout << "队列链表不存在!!!" << endl;
              return;
       }
       Link p = L, e, q;
       cout << "请输入人们持有的密码:";
       cin >> p->code;
       p->num = 1;    //无头节点所以要先赋值
       for (int i = 1; i < n; i++)    //人们入队
       {
              e = new LNode;
              e->num = i + 1;
              cin >> e->code;
              e->next = L;
              p->next = e;
              p = p->next;
       }
       q = p;
       p = p->next;
       cout << "出队的人顺序为:";
       while (1)
       {
              if (p->next == p)    //只剩下一人
              {
                     cout << p->num<< endl;
                     delete p;
                     break;
              }
              m--;
              if (m == 0)    //第m个
              {
                     cout << p->num<< ' ';
                     q->next =p->next;    //删除节点
                     m = p->code;    //给m重新赋值
                     e = p;
                     p = p->next;
                     delete e;
              }
              else
              {
                     q = p;
                     p = p->next;
              }
       }
}
intmain()
{
       int n, m;
       while (1)
       {
              Link L;
              InitList(L);
              cout << "请输入要输入的数据的个数(0结束):";
              cin >> n;
              if (n == 0&&n>30)
                     break;
              cout << "请输入上限值为:";
              cin >> m;
              Leave(L, n, m);
       }
       return 0;
}


 

题目三:Dr.Kong设计了一件艺术品(****)

[问题描述]

Dr.Kong设计了一件艺术品,该艺术品由N个构件堆叠而成,N个构件从高到低按层编号依次为1,2,……,N。艺术品展出后,引起了强烈的反映。Dr.Kong观察到,人们尤其对作品的高端部分评价甚多。

狂热的Dr.Kong一激动,对组成该艺术品的N个构件重新组合,比如:把第6层到第12层的构件搬下来,想一想,然后整体放到剩下构件的第7层下面;过一会儿,又把第2层到第9层的构件搬下来,整体放到剩下构件的第1层下面等等。于是,Dr.Kong在进行了连续若干次“搬来搬去”后,还是这N个构件,又诞生了一件新的艺术品。

编程:请输出新的艺术品最高十层构件的编号。

 

标准输入

第一行: N K       表示构件的总数和“搬来搬去”的总次数

第2~K+1行:A B C    表示要搬动的构件(即从第A层到第B层)整个放在第C层下面;

如果C等于0,则要搬动的构件将放到最高层。

标准输出

由十行组成,分别为组成新艺术品的第一层到第十层构件的编号。

约束条件

(1)   10≤N≤20000    1≤k≤1000

(2)   1≤A≤B≤N,     0≤C≤N-(B-A+1)

样  例

提示:样例中仅是常规的测试数据输入及对应结果,特殊情况需要全面考虑,自己设计测试数据验证算法的健壮性。

标准输入(测试数据):

13 3

6 12 1

2 9 0

10 13 8

 

标准输出结果:

6    7  8  9  10  11  12  2  3  4  5  13  1

1、总体设计(设计思想)

本题的重点是构建单链表,截取单链表。首先,构建从1~n的单链表,截取单链表跟删除单链表的节点相似,吧指针指向控制好就行了。

3、功能截图展示:


3、程序清单

#include<stdio.h>
#include<iostream>
usingnamespace std;
typedefstruct LNode
{      int data;
       struct LNode *next;
}LNode,*LinkList;
 
voidCreateList_L(LinkList &L,int n)
{//创建节点数为n的单链表
       LNode *p;
       L= new LNode[sizeof(LNode)]; //头结点
       L->next=NULL;
       for(int i=n;i>0;i--)
       {
              p=new LNode[sizeof(LNode)];
              p->data=i;
              p->next=L->next;
              L->next=p;
       }
}
voidMoveList_L(LinkList &L,int l,int r,int n)
{//移动结点的函数
       int i=0;
       LNode *p=L,*q=L;
       LNode *newL;
       while(p&&i<l-1)
       {
              p=p->next;
              ++i;
       }
       i=0;
       while(q&&i<r)
       {
              q=q->next;
              ++i;
       }
       newL=p->next;    //将截取下来的一段单链表保存在newL中
       p->next=q->next;
 
       i=0;p=L;
       while(p&&i<n)
       {
              p=p->next;
              i++;
       }
       q->next=p->next;   //插入之前截取下来的单链表newL
       p->next=newL;
}
voidPrintfList_L(LinkList &L)
{//输出单链表中的元素
       LNode *p;
       p=L->next;
       while(p)
       {
              cout<<p->data<<"  ";
              p=p->next;
       }
       cout<<endl;
}
intmain()
{
       LNode *L;
       int n,k,a,b,c;
       cout<<"请输入构件的总数和“搬来搬去”的总次数:"<<endl;
       cin>>n>>k;
       CreateList_L(L,n);
       cout<<"请输入要搬动的构件(即从第A层到第B层)整个放在第C层下面:"<<endl<<"如果C等于0,则要搬动的构件将放到最高层。"<<endl;
       while(k--)
       {
              cin>>a>>b>>c;
              MoveList_L(L,a,b,c);
       }
       PrintfList_L(L);
       return 0;
}
 


  • 6
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值