第一章作业3-链式存储结构及其操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fighting123678/article/details/82691930

一、单选题
1、

这里写图片描述


2、

这里写图片描述

答案:D

解析:
因为h不带头结点,所以h指的就是第一个元素,在第一个元素前面插入t,所以t的下一个指向h,之后,h重新变为指向第一个元素;

头指针—头结点—首元结点


3、

这里写图片描述

单链表的插入
因为在找位置的时候,是一个个找的,因此要用一个变量不断指向线性表的下一个元素;

Status ListInsert_L(LinkList&L,int i,ElemType e)//在线性表第i个位置插入元素e//插入和创建不一样,插入是在创建的基础上进行的改动;
{
    LinkList p;
    p=L;//因为现在需要找的位置是插入位置的前一个,插入的位置也有可能为头结点的后面,因此以p为起点;
    int j=0;//因为以p为起点,所以j的初始值为0;
    while(p&&j<i-1)//这里是在寻找要插入结点位置的前一个
    {
        p=p->next;
        j++;
    }
    if(!p||j>i-1) return ERROR;//p为空的话就停止;
    LinkList s;
    s=(LinkList)malloc(sizeof(LNode));//要为插入的地方创建新的结点;
    s->data=e;//千万不要忘记在创建结点之后给新结点赋值;
    s->next=p->next;
    p->next=s;
    return OK;
}

千万不要忘记在创建新结点之后赋值
插入的时候,先要找到前一个插入的位置,因为插入的位置也有可能为头结点的后面,因此以p为起点,所以j的初始值为0(这里还用了一个变量j是因为怕有错误的位置出现)。找到位置之后,创建新的结点,输入元素,然后再将新结点放到找到的p的位置的后面;


4、

这里写图片描述

答案:A


5、

这里写图片描述

答案:B

解析:
头指针—(头结点)(可以没有)—首元结点
(1)头结点中可以不存储任何信息,也可以存储线性表的长度的附加信息,头结点的指针域指向第一个元素结点存储的位置。头结点的设定是为了操作方便。
(2)头指针是指向链表中第一个结点的指针。若链表中有头结点,那么头指针所指结点为线性表的头结点;若链表中不设头结点,那么该头指针所指结点为该线性表的首元结点;
(3)链表增加头结点的作用如下:
一是:便于首元结点的处理。增加了头结点后,首元结点的地址保留在头结点的指针域中,则对链表的第一个数据元素的操作与其它数据元素相同,无需进行特殊处理。
二是:便于空表和非空表的统一处理。当链表不设头结点的时候,假设L为单链表的头指针,它应该指向首元结点,则当单链表为长度n为0的空表的时,L指针为空(判断空表的条件可记为L==NULL)//L为头指针,L的指针为空指针增加头结点后,无论链表是否为空,头指针都是指向头结点的非空指针。若为非空单链表,头指针指向头结点。若为空表,则头结点的指针域为空(判定空表的条件可记为L->next==NULL)//L为头指针,L所指的下一个的指针域为空


6、

这里写图片描述

答案:A


7、

这里写图片描述

答案:C


8、

这里写图片描述

答案:D


二、函数题

1、循环单链表区间删除 (15 分)

本题要求实现带头结点的循环单链表的创建和单链表的区间删除。L是一个带头结点的循环单链表,函数ListCreate_CL用于创建一个循环单链表,函数ListDelete_CL用于删除取值大于min小于max的链表元素。
函数接口定义:

 Status ListCreate_CL(LinkList &CL); 
    void ListDelete_CL(LinkList &CL,ElemType min,ElemType max);

裁判测试程序样例:

//库函数头文件包含
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型  

typedef struct LNode
{  
    ElemType data;  
    struct LNode *next; 
}LNode,*LinkList; //循环单链表类型定义与单链表定义相同,区别在尾节点next取值

Status ListCreate_CL(LinkList &CL);  

void ListDelete_CL(LinkList &CL, ElemType min, ElemType max);

void ListPrint_CL(LinkList &CL) 
{   //输出单链表,空表时输出Empty List。 
    LNode *p=CL->next;  //p指向第一个元素结点
    if(p==CL){
      printf("Empty List");
      return;
    }
    while(p!=CL)  
    {   
        if(p->next!=CL)
            printf("%d ",p->data);   
        else
            printf("%d",p->data);      
        p=p->next; 
    } 
}    
int main() 
{  
    LinkList CL;
    ElemType min,max;
    if(ListCreate_CL(CL)!= OK) 
    {
       printf("循环链表创建失败!!!\n");
       return -1;
    }
    scanf("%d%d",&min,&max);    
    ListDelete_CL(CL,min,max);   
    ListPrint_CL(CL);  	
    return 0;
}

/* 请在这里填写答案 */

输入格式: 第一行输入一个整数n,表示循环单链表中元素个数,接下来一行共n个整数,中间用空格隔开。第三行输入min和max。

输出格式: 输出删除后循环链表的各个元素,两个元素之间用空格隔开,最后一个元素后面没有空格。

输入样例

6
1 2 3 4 5 6
2 5

输出样例:

1 2 5 6

答案

Status ListCreate_CL(LinkList &CL)
{
    CL=(LinkList)malloc(sizeof(LNode));
    if(!CL) exit(OVERFLOW);
    CL->next=CL;
    int n;
    scanf("%d",&n);
    LinkList p,r;
    p=CL;
    for(int i=0;i<n;i++)
    {
        r=(LinkList)malloc(sizeof(LNode));
        if(!r) exit(OVERFLOW);
        scanf("%d",&r->data);
        r->next=p->next;
        p->next=r;
        p=r;
    }
    return OK;
}

void ListDelete_CL(LinkList &CL,ElemType min,ElemType max)
{
    LinkList p,r;
    p=CL;
    while(p->next!=CL)//注意判别条件不是p,也不是p!=CL;
    {
        if(p->next->data>min&&p->next->data<max)//比较大小的是p->next->data,千万不要忘记了next
        {
            r=p->next;
            p->next=r->next;
            free(r);
        }
        //p=p->next;
        else p=p->next;//这里必须是else
    }
}

注意:
(1)注意判别条件不是p,也不是p!=CL;
(2)比较大小的是p->next->data,千万不要忘记了next
(3)else p=p->next;这里必须是else
插入操作中,是用head搭建起re和cu之间的桥梁,用cu创建一个新结点,创建完之后,输入数值,把cu放到链表中,re指向cu,不断这样循环完之后,因为是双向链表,所以re的下一个指向head,同时在这里,head起到桥梁的作用,CL=head;


2、 单链表元素定位 (12 分)

本题要求在链表中查找第一个数据域取值为x的节点,返回节点的位序。L是一个带头结点的单链表,函数ListLocate_L(LinkList L, ElemType x)要求在链表中查找第一个数据域取值为x的节点,返回其位序(从1开始),查找不到则返回0。例如,原单链表各个元素节点的元素依次为1,2,3,4,则ListLocate_L(L, 1)返回1,ListLocate_L(L, 3)返回3,而ListLocate_L(L, 100)返回0。
函数接口定义:

int ListLocate_L(LinkList L, ElemType x);

其中 L 是一个带头节点的单链表。 x 是一个给定的值。函数须在链表中查找第一个数据域取值为x的节点。若找到则返回其位序(从1开始),找不到则返回0。
裁判测试程序样例:

//库函数头文件包含
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

//函数状态码定义
#define TRUE        1
#define FALSE       0
#define OK          1
#define ERROR       0
#define INFEASIBLE -1
#define OVERFLOW   -2

typedef int  Status;
typedef int  ElemType; //假设线性表中的元素均为整型

typedef struct LNode
{
    ElemType data;
    struct LNode *next;
}LNode,*LinkList;

Status ListCreate_L(LinkList &L,int n)
{
    LNode *rearPtr,*curPtr;   //一个尾指针,一个指向新节点的指针
    L=(LNode*)malloc(sizeof (LNode));
    if(!L)exit(OVERFLOW);
    L->next=NULL;               //先建立一个带头结点的单链表
    rearPtr=L;  //初始时头结点为尾节点,rearPtr指向尾巴节点
    for (int i=1;i<=n;i++){  //每次循环都开辟一个新节点,并把新节点拼到尾节点后
        curPtr=(LNode*)malloc(sizeof(LNode));//生成新结点
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);//输入元素值
        curPtr->next=NULL;  //最后一个节点的next赋空
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
//下面是需要实现的函数的声明
int ListLocate_L(LinkList L, ElemType x);

int main()
{
    LinkList L;
    int n;
    int x,k;   
    scanf("%d",&n);  //输入链表中元素个数
    if(ListCreate_L(L,n)!= OK) {
          printf("表创建失败!!!\n");
          return -1;
    }
   scanf("%d",&x); //输入待查找元素
   k=ListLocate_L(L,x);
   printf("%d\n",k);
   return 0;
}

/* 请在这里填写答案 */

输入样例:

4
1 2 3 4
1

输出样例:

1

答案

int ListLocate_L(LinkList L, ElemType x)
{
    LinkList p;
    p=L->next;
    int i=1;
    while(p)
    {
        if(p->data==x) return i;
        else
        {
            i++;
            p=p->next;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fighting123678/article/details/82691930