线性表及其应用

该实验涉及C语言编程,通过顺序表和单链表实现线性表的创建、插入和输出。顺序表通过数组实现,支持输入元素并输出顺序表的长度。单链表采用尾插法构建,允许用户输入数据元素,直至输入-1结束。实验还涵盖了线性表在链式存储结构中的插入和删除操作。
摘要由CSDN通过智能技术生成

实验名称      线性表及其应用                  

一、实验目的:

 1.熟悉C语言的上机环境,进一步掌握C语言的结构特点。

2.掌握线性表的顺序存储结构的定义及C语言实现。

3.掌握线性表的链式存储结构——单链表的定义及C语言实现。

4.掌握线性表在顺序存储结构即顺序表中的各种基本操作。

5.掌握线性表在链式存储结构——单链表中的各种基本操作。

二、实验环境:

Visual C++

三、实验内容:

(写出主要的内容)

  1. 建立含n个数据元素的顺序表并输出该表中各元素的值及顺序表的长度。
#include<stdio.h>
typedef struct
{
       int elem[100];
       int last;
}SqeList;

int main()
{
       SqeList  L,*p;
       printf("请输入顺序表的长度:");
       scanf("%d",&L.last);
       for(int i=0;i<=L.last;i++)
              L.elem[i]=i;
       p=&L;
       for(i=1;i<=L.last;i++)
              printf("%d ",p->elem[i-1]);
       printf("\n顺序表的长度:%d\n",L.last);
       return 0;
}

结果如下:

请输入顺序表的长度:10

0 1 2 3 4 5 6 7 8 9

顺序表的长度:10

  1. 利用前面的实验先建立一个顺序表L={21,23,14,5,56,17,31},然后在第i个位置插入元素68。
 #include <stdio.h>
#define MAXSIZE 100
#define OVERFLOW -2
#define OK 1
#define ERROR  0
typedef int Status;
typedef int elemtype;
typedef struct
{
       elemtype vec[MAXSIZE];
       int length;
}sqList;
Status initList(sqList &L,int k)//线性表的初始化
{
       int i;
       L.length=k;//!
       printf("input the List:\n");
       for(i=0;i<k;i++)
       {
              scanf("%d",&L.vec[i]);
       }
       return OK;
}
int insert(sqList &L,int i,int x)//线性表的插入 //记得要加&
{
       int j;
       if(L.length>=MAXSIZE) 
       {    printf("the List is OVERFLOW.\n");
            return ERROR;
       }
       else if((i<1)||(i>L.length+1))
       {
              printf("position is not correct.\n");
              return ERROR;
       }
       else
       {   printf("input the List:");
              for(j=L.length-1;j>=i-1;j--)
              {
                     L.vec[j+1]=L.vec[j];
              }
              L.vec[i]=x;
              L.length++;
       }
       return OK;
}
int main()
{
       int i,n,x;
       sqList la;
       printf("iuput the the length of List:");//输入表的长度
       scanf("%d",&n);
       initList(la,n);
       printf("iuput the insert location:");
       scanf("%d",&i);
       printf("iuput the insert number:");
       scanf("%d",&x);
       if(insert(la,i,x))//输出插入后线性表的长度和数据
       {
              printf("the new List's length is:%d\n",la.length);
              printf("the new List's data is:\n");
              for(i=0;i<la.length;i++)
              printf("%d ",la.vec[i]);
       }
       else
       {
             
              printf("can't insert the data!\n");
       }
       return 0;
}

输出结果:

iuput the the length of List:7

input the List:

21 23 14 5 56 17 31

iuput the insert location:3

iuput the insert number:68

input the List:the new List's length is:8

the new List's data is:

21 23 14 68 5 56 17 31

  1. 建立一个带头结点的单链表,结点的值域为整型数据。要求将用户输入的数据按尾插入法来建立相应单链表。
#include <stdio.h>
#include <stdlib.h>
typedef struct k
{
  int data;
  struct k* next;
}Node; /*创建链表*/



Node* initList()
{ /*初始化*/
  Node *h=(Node *)malloc(sizeof(Node));
  h->next=NULL;
  return h;
}
Node* creatList()
{ /*尾插法创建*/
  Node *h, *tail,*q;
  int x;
  h=(Node *)malloc(sizeof(Node));
  h->next=NULL;
  tail=h; /*tail类似于标签*/
  printf("input nums, endby -1:\n");
  scanf("%d",&x);
  while(x!=-1){
  //1、造结点q,并赋值;
  q=(Node *)malloc(sizeof(Node));
  q->data=x;
  q->next=NULL;
  //2、将q插入链表;
  tail->next=q;
  tail=q;
  //3、继续读
  scanf("%d",&x);
  }
  return h;
}
void printList(Node *h)
{ /*输出函数*/
  if(h->next==NULL) return;
  for(h=h->next;h!=NULL; h=h->next)
     if(h->next!=NULL)
            printf("%d->", h->data);
     else
            printf("%d",h->data);
}
int main()
{
Node *h;
h=creatList();
printf("\n链表为:\n");
printList(h);
}

输出结果为:

input nums, endby -1:

4 8 56 4 3 56 13 5 15 4 -1

 

链表为:

4->8->56->4->3->56->13->5->15->4

四、思考与提高

1. 如果按由表尾至表头的次序输入数据元素,应如何建立顺序表。

使用头插入法建立链表

2. 在main函数里如果去掉L=&a语句,会出现什么结果?

       无法传递地址

五、完整参考程序

    1.顺序线性表的建立、插入及删除。

#include <stdio.h>

#include <stdlib.h>

 

#define OK   1

#define ERROR  0

#define ElemType int

#define   MAXSIZE  100          /*此处的宏定义常量表示线性表可能达到的最大长度*/

typedef  struct

{

       ElemType  elem[MAXSIZE];  /*线性表占用的数组空间*/

       int       last;                    /*记录线性表中最后一个元素在数组elem[ ]中的位置(下标值),空表置为-1*/

}SeqList;

 

void initial(SeqList *v)         //初始化线性表

{//初始化线性表

 int i;

 printf("请输入初始线性表长度:n="); //输入线性表初始化时的长度

 scanf("%d",&v->last);

 printf("请输入从1到%d的各元素\n",v->last);

 getchar();

 for(i=0;i<v->last;i++) scanf("%d",&v->elem[i]); //输入线性表的各元素

 v->last--;

}

 

int  InsList(SeqList *L,int i,ElemType e)      //在线性表中插入元素

{

//实验完成该部分的内容

       int k;

       for(k=L->last;k>i-1;k--)

              L->elem[k+1]=L->elem[k];

       L->elem[i-1]=e;

       L->last++;

       return OK;

}

 

int  DelList(SeqList *L,int i,ElemType *e)    

/*在顺序表L中删除第i个数据元素,并用指针参数e返回其值。i的合法取值为1≤i≤L.last+1 */   

{

       //实验完成该部分的内容

       int k;

       if((i<1)||(i>L->last))

       {

              printf("删除的位置不合法!");

              return ERROR;

       }

       *e=L->elem[i-1];

       for(k=i;k<L->last;k++)

              L->elem[k-1]=L->elem[k];

       L->last--;

       return OK;

}

 

int  Locate(SeqList L, ElemType e)   

{    

       //实验完成该部分的内容

       int i=0;

       while((i<=L.last)&&L.elem[i]!=e)

              i++;

       if(i<=L.last)

              return(i+1);

       else

              return(-1);

}

 

void print(SeqList S)

{    

       int i;

       for(i=0;i<=S.last;i++)

              printf("%5d",S.elem[i]);

       printf("\n");

}

 

void main()

{SeqList S;      //S为一线性表

 int loc,flag=1;

 char j;

 int ch;

 int temp;

printf("本程序用来实现顺序结构的线性表。\n");

 printf("可以实现查找、插入、删除等操作。\n");

 initial(&S);         //初始化线性表

 while(flag)

    { printf("请选择:\n");

      printf("1.显示所有元素\n");

      printf("2.插入一个元素\n");

      printf("3.删除一个元素\n");

      printf("4.查找一个元素\n");

      printf("5.退出程序    \n");

      scanf(" %c",&j);

      switch(j)

       {case '1':print(S); break; //显示所有元素

        case '2':{printf("请输入要插入的元素和插入位置:\n");

                 printf("格式:数据,位置;例如:a,2\n");

                 scanf(" %d,%d",&ch,&loc);  //输入要插入的元素和插入的位置

                 temp=InsList(&S,loc,ch);     //插入

                 if(temp==ERROR)  printf("插入失败!\n");  //插入失败

                   else  {printf("插入成功!\n");   print(S);} //插入成功

                 break;

                }

        case '3':{printf("请输入要删除元素的位置:");

                 scanf("%d",&loc);    //输入要删除的元素的位置

                 temp=DelList(&S,loc,&ch);  //删除

                 if(temp==OK) printf("删除了一个元素:%d\n",ch); //删除成功

                 else printf("该元素不存在!\n");  //删除失败

                 print(S);

                 break;

                }

        case '4':{printf("请输入要查找的元素:");

                 scanf(" %d",&ch);      //输入要查找的元素

                 loc=Locate(S,ch);      //定位

                 if(loc!=-1) printf("该元素所在位置:%d\n",loc); //显示该元素位置

                 else    printf("%c 不存在!\n",ch);//当前元素不存在

                 break;

                }

        default:flag=0;printf("程序结束,按任意键退出!\n");

       }

    }

 getchar();

}

2.链式线性表的建立、插入及删除。

#include <stdio.h>

#include <stdlib.h>

#include <malloc.h>

 

#define OK   1

#define ERROR  0

#define TRUE 1

#define FALSE 0

 

typedef int ElemType;

typedef struct Node    /*结点类型定义*/

{

       ElemType data;

       struct Node  * next;

}Node, *LinkList;  /* LinkList为结构指针类型*/

 

void init_linklist(LinkList *l)/*对单链表进行初始化*/

{

       *l=(LinkList)malloc(sizeof(Node)); /*申请结点空间*/

       (*l)->next=NULL;                      /*置为空表*/

}

 

void CreateFromTail(LinkList L)

{

              //实验完成该部分的内容

Node *r, *s;

   int c;

   int  flag =1; /*设置一个标志,初值为1,当输入-1时,flag为0,建表结束*/

   r=L;                /*r指针动态指向链表的当前表尾,以便于做尾插入,其初值指向头结点*/

    printf("请输入数据,以-1结束:"); //输入生成单链表时的元素

while(flag)         /*循环输入表中元素值,将建立新结点s插入表尾*/

{

  scanf("%d",&c);

  if(c!=-1)

  {

   s=(Node*)malloc(sizeof(Node));

   s->data=c;

   r->next=s;

   r=s;

  }

  else

  {

   flag=0;

   r->next=NULL;   /*将最后一个结点的next链域置为空,表示链表的结束*/

  }

}

}

 

int InsList(LinkList L,int i,ElemType e)

/*在带头结点的单链表L中第i个位置插入值为e的新结点*/

//实验完成该部分的内容}

 

int DelList(LinkList L,int i,ElemType *e)

/*在带头结点的单链表L中删除第i个元素,并将删除的元素保存到变量*e中*/

//实验完成该部分的内容

Node *pre,*s;

   int k;

   if(i<=0) return ERROR;

   pre=L; k=0;

   while(pre!=NULL&&k<i-1)

   {

      pre=pre->next;

      k=k+1;

   }

   if(pre==NULL)

   {

      printf("插入位置不合理!");

      return ERROR;

   }

   s=(Node *)malloc(sizeof(Node));

   s->data=e;

   s->next=pre->next;

   pre->next=s;

   return OK;

 

}

 

int Locate( LinkList L,ElemType key)

/*在带头结点的单链表L中查找其结点值等于key的结点,若找到则返回该结点的位置p,否则返回NULL*/

{

       Node *p;

       int n=0;

       p=L->next;    /*从表中第一个结点开始 */

       while (p!=NULL)

       {

              n++;

              if (p->data!=key)

                     p=p->next;

              else 

                     break;      /*找到结点值=key时退出循环 */

       }

       if(p==NULL)n=0;

       return n;

}

 

Node * Get (LinkList  L, int i)

/*在带头结点的单链表L中查找第i个结点,若找到(1≤i≤n),则返回该结点的存储位置; 否则返回NULL*/

       //实验完成该部分的内容

int j;

   Node *p;

   if(i<=0)return NULL;

      p=L;j=0;

   while((p->next!=NULL)&&(j<i))

   {

      p=p->next;

      j++;

   }

   if(i==j) return p;

   else return NULL;

}  

 

void Print(LinkList v)  

{//显示链表所有元素

 LinkList q;

 q=v->next;

 printf("链表所有元素:");

 while(q!=NULL)

   {printf("%d ",q->data);q=q->next;}

 printf("\n");

}

 

void main()

{LinkList L;

 int temp;

 int num,loc,flag=1;

 char j;

 int ch;

 Node *node;

 printf("本程序实现链式结构的线性表的操作。\n");

 printf("可以进行插入,删除,定位,查找等操作。\n");

 init_linklist(&L);

 CreateFromTail(L);      //生成单链表

 Print(L);         

 while(flag)

    { printf("请选择:\n");

      printf("1.显示所有元素\n");  //显示链表元素

      printf("2.插入一个元素\n");  //插入链表元素

      printf("3.删除一个元素\n");  //删除链表元素

      printf("4.按关键字查找元素\n");  //按关键字查找

      printf("5.按序号查找元素\n"); //按序号查找

      printf("6.退出程序      \n");  //退出

      scanf(" %c",&j);

      switch(j)

       {case '1':Print(L); break;

        case '2':{printf("请输入元素(一个字符)和要插入的位置:\n");

                 printf("格式:数据,位置;例如:a,3\n");

                 scanf(" %d,%d",&ch,&loc);       //输入要插入的元素和要插入的位置

                 temp=InsList(L,loc,ch);      //插入

                 if(temp==ERROR) printf("插入失败!\n"); //插入失败

                 else printf("插入成功!\n"); //成功插入

                 Print(L);

                 break;

                }

        case '3':printf("请输入要删除的元素所在位置:");

                scanf("%d",&loc);              //输入要删除的节点的位置

                temp=DelList(L,loc,&ch);    //删除

                if(temp==ERROR) printf("删除失败!\n"); //删除失败

                else printf("成功删除了一个元素:%d\n",ch);   //删除成功,显示该元素

                Print(L);

                break;

        case '4':if(L->next==NULL)                   //链表为空

                   printf("链表为空!\n");

                else{printf("请输入要查找的元素:");

                     scanf(" %d",&ch);                //输入要查找的元素

                     ch=Locate(L,ch); //按关键字查找

                     if(ch==0) printf("没有找到该元素!\n"); //查找失败

                     else printf("该元素在链表的第%d个位置。\n",ch);

                                           //成功查找,显示该元素位置

                    }

                break;

        case '5':if(L->next==NULL)                   //链表为空

                   printf("链表为空!\n");

                else{printf("请输入要查找的位置:");

                     scanf("%d",&loc);    //输入要查找的元素的位置

                     node=Get(L,loc); //按序号查找

                     if(node==NULL) printf("该位置不存在!\n"); //查找失败

                     else printf("第%d个元素是:%d\n",loc,node->data);

                                //成功查找,显示该元素

                    }

                break;

        default:flag=0;printf("程序结束,按任意键退出!\n");

       }

    }

getch();

}

五、心得体会:

1、如何使用不同方法建立链表

2、头插入法与尾插入法的不同

3、数据结构储存位置的分配

4、顺序插入与链表插入的不同

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这是一个关于约瑟夫环的问题。约瑟夫(Joseph)是指编号为1、2、3……n的n个人按顺时针方向围坐在一圈。每个人持有一个密码(正整数)。一开始,任意指定一个正整数作为报数上限值m。从第一个人开始顺时针地逐个报数,到第m个人时停止报数。同时,这个人要将自己的密码告诉旁边的人。然后,从他的下一个人开始再次顺时针逐个报数,直到报到第m个人时再次停止报数,并告诉旁边的人自己的密码。如此循环进行下去,直到最后只剩下一个人为止。这个问题要求选择一个正整数作为报数上限值m,使得在指定的n个人中,最后留下的那个人所持有的密码在第一个人开始报数时被报出来。 ### 回答2: 约瑟夫环是一种经典的问题,其基本思路是利用循环链表模拟人围成环形的场景,从而通过一定规则不断删除元素,直到只剩下一个元素为止。这个问题涉及到了线性表中的循环链表、链式存储结构、循环操作等内容,具有很强的实际应用价值。 解决约瑟夫环问题的基本思路是,从第一个人开始报数,每次报到m就出列,直到所有人都出列为止。为了能够便捷地删除被淘汰的人,我们需要采用链表的方式来实现。在具体实现时,我们可以将所有人看作链表中的结点,将它们通过指针相连成为一个循环链表。由于循环链表的最后一个结点指向链表的第一个结点,因此可以实现“环形”的效果。 当然,在实际计算中还需要进行一些优化。比如,当当前报数的人数大于m时,可以利用循环操作,方便地将当前结点移到距离它m位置后面的结点。此外,由于报数是环形的,因此我们需要对序号进行取模操作。具体算法步骤如下: 1、将所有人构成一个循环链表。 2、从第一个人开始报数(从1开始),每次报数都将当前结点移至距离它m的后面一个结点。 3、当当前人数小于或等于m时,删除当前节点,直至只剩下一个结点。 4、输出剩下的这个结点的编号,即为最后获胜者的编号。 总的来说,约瑟夫环是一个非常有趣的问题,它不仅仅涉及到数据结构与算法方面的知识,还可以帮助我们锻炼逻辑思维和问题解决能力。同时,它也具有很多实际应用价值,比如密码学领域中的随机数生成、进程管理等方面。因此,我们应当及时学习与掌握这个问题的解决方法,以便更好地应对各种挑战。 ### 回答3: 一开始,让第一个人从1开始报数,依次下去,凡报到m的倍数的人都要出列,直到最后只剩下一个人为止。这个人就是约瑟夫环问题的解。约瑟夫环问题可以用线性表来解决。 线性表是指由n个数据元素$ {a_1,a_2,...,a_n} $ 组成的有限序列,这些元素可以是基本数据类型或者结构类型,它们之间的关系是线性的,即前驱后继关系唯一确定。 对于约瑟夫环问题,我们可以用线性表来表示。可以用顺序表、链表或循环链表来实现。其中,循环链表最符合问题的特点,因为它可以将表首和表尾相连,形成一个环。 具体实现方法是,将n个人依次插入循环链表中,每个结点存储一个密码和一个指向下一个结点的指针。然后,从表头开始,每次数到m,就删除相应的结点,直到只剩下一个结点为止。最后留下的这个结点就是问题的解。 约瑟夫环问题有很多种求解方法,除了线性表之外,还可以用递归、数学公式等方法来求解。但是,用线性表来解决问题具有简单易懂、效率高等优点,是最常用的方法之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值