数据结构作业5重难点复习

一、判断题

在这里插入图片描述

1-1 反了

1-2在这里插入图片描述
链表是链式存储结构,表中元素的地址不一定连续

1-3 O(n)或O(m) 看你把谁连在后面

二、选择题

在这里插入图片描述

带头结点的单链表,头结点是固定存在的,其next域指向链表的第一个元素,如果next域为空,说明链表中没有元素,即为空。

在这里插入图片描述

前一链表的最大元素也比后一链表的最小元素小

在这里插入图片描述

其他三项均为链表的特点

在这里插入图片描述

遍历长度为m的链表找到其为元素,时间复杂度为O(m)

在这里插入图片描述
在这里插入图片描述

注意与带头结点的相比较

2-18
可以用带表头附加结点的链表表示线性表,也可以用不带头结点的链表表示线性表,前者最主要的好处是(B)。(2分)
A.可以加快对表的遍历
B.使空表和非空表的处理统一
C.节省存储空间
D.可以提高存取表元素的速度

三、编程题

6-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)
{
    LNode* p;
    p = L->next;
	if(!p) return ERROR;//空表
    int i=1;
    while (p && p!=NULL)//遍历
    {
    	 if(p->data==x)//找到
    {
        return i;
    } 
        i++;//记录位序
		 p = p->next;
    }
    return 0;
}

6-3 删除单链表中最后一个与给定值相等的结点 (10分)

本题要求在链表中删除最后一个数据域取值为x的节点。L是一个带头结点的单链表,函数ListLocateAndDel_L(LinkList L, ElemType x)要求在链表中查找最后一个数据域取值为x的节点并将其删除。例如,原单链表各个节点的数据域依次为1 3 1 4 3 5,则ListLocateAndDel_L(L,3)执行后,链表中剩余各个节点的数据域取值依次为1 3 1 4 5。
函数接口定义:

void ListLocateAndDel_L(LinkList L, ElemType x)

其中 L 是一个带头节点的单链表。 x 是一个给定的值。函数须在链表中定位最后一个数据域取值为x的节点并删除之。

裁判测试程序样例:


//库函数头文件包含
#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
#define NULL        0

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;
    for (int i=1;i<=n;i++){
        curPtr=(LNode*)malloc(sizeof(LNode));
        if(!curPtr)exit(OVERFLOW);
        scanf("%d",&curPtr->data);
        curPtr->next=NULL;
        rearPtr->next=curPtr;
        rearPtr=curPtr;
    }
    return OK;
}
//链表输出函数
void ListPrint_L(LinkList L)
{
    LNode *p=L->next;
    if(!p){
        printf("空表");
        return;
    }
    while(p!=NULL)
    {
       if(p->next!=NULL)
           printf("%d ",p->data);
       else
           printf("%d",p->data);
          p=p->next;
    }
}
//下面是需要实现的函数的声明
void ListLocateAndDel_L(LinkList L, ElemType x);

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

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

输入样例:

6
1 3 1 4 3 5
3

输出样例:

1 3 1 4 5

//思路:创建两个指针,一个指向当前结点,一个指向它的前驱,遍历找到链表中最后一个符合的结点以及其前驱结点,删除该结点后释放
//注意:一 空表,二 想要找的元素不存在 
void ListLocateAndDel_L(LinkList L, ElemType x)
{
	LNode *p,*q;
	if(!L) return;
	else
	{
		p=L->next; q=L;//q指向头结点
		LNode *s=p;
		while (p)
		{
			if(p->data==x) q=s;//记录并更新相同位置(q也是要删除位置的直接前驱)
			s=p;//这两步就是不等就一直往后更新
			p=p->next;
		}
		if(q!=L)//大概的意思就是q往后移动了,就可以删了
		{
			q->next=q->next->next;//执行删除 
			free(p);
		}
	}
}

7-1 两个有序链表序列的合并 (20分)

已知两个非降序链表序列S1S2,设计函数构造出S1S2合并后的新的非降序链表S3

输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:
在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。

输入样例:

1 3 5 -1
2 4 6 8 10 -1

输出样例:

1 2 3 4 5 6 8 10
//思路:创建三个指针,一个指向第一个链表,另一个指向第二个,第三个指向新链表,比较两个链表中元素的大小,将小的赋给指针三,指针后移
//注意:一 当两个链表中元素相同时,只需要将其中的一个赋给指针三0      二 链表为空时输出NULL
//库函数头文件包含
#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;

//链表创建函数
void ListInput_L(LinkList &L)
{
	L=(LNode*)malloc(sizeof(LNode));	
	L->next=NULL;//建立一个带头结点的新链表
	if(!L) exit(OVERFLOW); 
	LNode* p=L,*t;//一个尾指针,一个指向新节点的指针 
	int e;
    scanf("%d",&e);
	while(e!=-1)
	{
		t=(LNode*)malloc(sizeof(LNode));//开辟新空间用来存放新数据 
		t->data=e;
		t->next=NULL;
		p->next=t;
		p=t;
		scanf("%d",&e);
	} 
	/*while (1)
	{
		int e;
		scanf("%d",&e);
	    p->next->data=e;//error,未开辟新空间 
		if(e==-1) break;
		p=p->next; 
	}
	p->next=NULL;
	L=p;*/
}

LinkList MergeList_L(LNode* &la,LNode* &lb)
{
	LNode*pa,*pb,*pc;
	LinkList lc;
	pa=la->next;pb=lb->next;
	lc=(LNode*)malloc(sizeof(LNode));lc->next=NULL;//合并后的新链表
	if(!lc) exit(OVERFLOW); 
	pc=lc; 
	while(pa&&pb)
	{
		if(pa->data>=pb->data)//比较两个链表中元素的大小
		{
			pc->next=pb;//将小的赋给指针三
			pb=pb->next;//指针后移
			pc=pc->next;
	    }
		else
	    {
			pc->next=pa;
			pa=pa->next;
			pc=pc->next;
		}
	}
	if(!pa)
	{
		pc->next=pb;free(la);
	}
	else 
	{	
		pc->next=pa;free(lb);
	}
	return lc;
}
//链表输出函数
void ListPrint_L(LinkList &L)
{
	LNode *p=L->next;
	if(!p){
	    printf("NULL");
	    return;
	}
	while(p!=NULL)
	{
       if(p->next!=NULL)
           printf("%d ",p->data);
       else
           printf("%d",p->data);
   	   p=p->next;
	}
}
int main()
{
    LinkList La,Lb,Lc;
    ListInput_L(La);
    ListInput_L(Lb);
    Lc=MergeList_L(La,Lb);
    ListPrint_L(Lc);
    return 0;
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值