数据结构练习题-算法设计题-线性表

2023-11-16

算法设计

1将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中不允许有重复的数据。

[题目分析]

合并后的新表使用头指针Lc指向,pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的最后。如果两个表中的元素相等,只摘取La表中的元素,删除Lb表中的元素,这样确保合并后表中无重复的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素直接链接在Lc表的最后。

[算法描述]

void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc)
{//合并链表La和Lb,合并后的新表使用头指针Lc指向
	pa=La->next;  pb=Lb->next;    
    //pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
    Lc=pc=La;  //用La的头结点作为Lc的头结点
    while(pa && pb)
    {
	    if(pa->data<pb->data)
		{//取较小者La中的元素,将pa链接在pc的后面,pa指针后移
			pc->next=pa;
			pc=pa;
			pa=pa->next;
		}
    	else if(pa->data>pb->data)
		{ //取较小者Lb中的元素,将pb链接在pc的后面,pb指针后移
			pc->next=pb; 
			pc=pb; 
			pb=pb->next;
		}
     	else 
        {//相等时取La中的元素,删除Lb中的元素
			pc->next=pa;
			pc=pa;
			pa=pa->next;
          	q=pb->next;
			delete pb ;
			pb =q;
        }
     }
    pc->next=pa?pa:pb;    //插入剩余段
     delete Lb;            //释放Lb的头结点
}  

2将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。表中允许有重复的数据。

[题目分析]

合并后的新表使用头指针Lc指向,pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,依次摘取其中较小者重新链接在Lc表的表头结点之后,如果两个表中的元素相等,只摘取La表中的元素,保留Lb表中的元素。当一个表到达表尾结点,为空时,将非空表的剩余元素依次摘取,链接在Lc表的表头结点之后。

[算法描述]

void MergeList(LinkList& La, LinkList& Lb, LinkList& Lc, ) 
{//合并链表La和Lb,合并后的新表使用头指针Lc指向
	pa=La->next;//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
	pb=Lb->next;
  	Lc=pc=La; //用La的头结点作为Lc的头结点 
  	Lc->next=NULL;
 	while(pa||pb )
	{//只要存在一个非空表,用q指向待摘取的元素
    	if(!pa)  
		{//La表为空,用q指向pb,pb指针后移
			q=pb;  
			pb=pb->next;
		}
    	else if(!pb)  
		{//Lb表为空,用q指向pa,pa指针后移
			q=pa;  
			pa=pa->next;
		} 
    	else if(pa->data<=pb->data)  
		{//取较小者(包括相等)La中的元素,用q指向pa,pa指针后移
			q=pa;  
			pa=pa->next;
		}
    	else 
		{//取较小者Lb中的元素,用q指向pb,pb指针后移
			q=pb;  
			pb=pb->next;
		}
     	q->next = Lc->next;  
		Lc->next = q;  //将q指向的结点插在Lc 表的表头结点之后
    }
    delete Lb;             //释放Lb的头结点
}

3已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。

[题目分析]

只有同时出现在两集合中的元素才出现在结果表中,合并后的新表使用头指针Lc指向。pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果两个表中相等的元素时,摘取La表中的元素,删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个到达表尾结点,为空时,依次删除另一个非空表中的所有元素。

[算法描述]

void Mix(LinkList& La, LinkList& Lb, LinkList& Lc) 
{  
	pa=La->next;pb=Lb->next;//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
	Lc=pc=La; //用La的头结点作为Lc的头结点
	while(pa&&pb)
	{ 
		if(pa->data==pb->data)//交集并入结果表中。
		   { 
		      	pc->next=pa;pc=pa;pa=pa->next;
			  	u=pb;pb=pb->next; delete u;
			}
		    else if(pa->data<pb->data) 
		    {
		  		u=pa;pa=pa->next; delete u;
		    }
			else 
			{
				u=pb; pb=pb->next; delete u;
			}
	}
	while(pa) 
	{// 释放结点空间
		u=pa; 
		pa=pa->next; 
		delete u;
	}
	while(pb) 
	{//释放结点空间
		u=pb; 
		pb=pb->next; 
		delete u;
	}
	pc->next=null;//置链表尾标记。
	delete Lb;  //释放Lb的头结点
   }

4已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B 的差集(即仅由在A中出现而不在B中出现的元素所构成的集合),并以同样的形式存储,同时返回该集合的元素个数。

[题目分析]

求两个集合A和B的差集是指在A中删除A和B中共有的元素,即删除链表中的相应结点,所以要保存待删除结点的前驱,使用指针pre指向前驱结点。pa和pb分别是链表LaLb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果La表中的元素小于Lb表中的元素,pre置为La表的工作指针pa删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个为空时,依次删除另一个非空表中的所有元素。

[算法描述]

void Difference(LinkList& La, LinkList& Lb,int *n)
{//差集的结果存储于单链表La中,*n是结果集合中元素个数,调用时为0
	pa=La->next; pb=Lb->next;      
	//pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
	pre=La;//pre为La中pa所指结点的前驱结点的指针
	while(pa&&pb)
	{
		if(pa->data<q->data)
		{//A链表中当前结点指针后移
			pre=pa;pa=pa->next;*n++;
		} 
		else 
		if(pa->data>q->data)
			q=q->next;    //B链表中当前结点指针后移
		else 
		{
			pre->next=pa->next;      //处理A,B中元素值相同的结点,应删除
	        u=pa; pa=pa->next; delete u; //删除结点
			 
		}  
	}
}

5设计算法将一个带头结点的单链表A分解为两个具有相同结构的链表B、C,其中B表的结点为A表中值小于零的结点,而C表的结点为A表中值大于零的结点(链表A中的元素为非零整数,要求B、C表利用A表的结点)。

[题目分析]

B表的头结点使用原来A表的头结点,为C表新申请一个头结点。从A表的第一个结点开始,依次取其每个结点p,判断结点p的值是否小于0,利用前插法,将小于0的结点插入B表,大于等于0的结点插入C表。

[算法描述]

void DisCompose(LinkedList A)
{ 	 
	B=A;
	ext= NULL;//B表初始化
    C=new LNode;//为C申请结点空间
    C->next=NULL;//C初始化为空表
    p=A->next;//p为工作指针
    while(p!= NULL)
    { 
		r=p->next;//暂存p的后继
       	if(p->data<0)
        {//将小于0的结点链入B表,前插法
			p->next=B->next; B->next=p; 
		}
       else 
	   {//将大于等于0的结点链入C表,前插法
	  		p->next=C->next; C->next=p; 
	   }
       p=r;//p指向新的待处理结点。
     }
}

6设计一个算法,通过一趟遍历在单链表中确定值最大的结点。

[题目分析]

假定第一个结点中数据具有最大值,依次与下一个元素比较,若其小于下一个元素,则设其下一个元素为最大值,反复进行比较,直到遍历完该链表。

[算法描述]

ElemType Max (LinkList L ){
	if(L->next==NULL) 
		return NULL;
	pmax=L->next; //假定第一个结点中数据具有最大值
	p=L->next->next;
	while(p != NULL ){//如果下一个结点存在
		if(p->data > pmax->data) 
			pmax=p;//如果p的值大于pmax的值,则重新赋值
		p=p->next;//遍历链表
	}
	return pmax->data;
}

7设计一个算法,通过遍历一趟,将链表中所有结点的链接方向逆转,仍利用原表的存储空间。

[题目分析]

从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部。

[算法描述]

void  inverse(LinkList &L) 
{//逆置带头结点的单链表 L
    p=L->next;  
	L->next=NULL;
    while(p){
        q=p->next;//q指向*p的后继
        p->next=L->next;
        L->next=p;//*p插入在头结点之后
        p = q;
    }
}

8设计一个算法,删除递增有序链表中值大于mink且小于maxk的所有元素(mink和maxk是给定的两个参数,其值可以和表中的元素相同,也可以不同 )。

[题目分析]

分别查找第一个值>mink的结点和第一个值 ≥maxk的结点,再修改指针,删除值大于mink且小于maxk的所有元素。

[算法描述]

void delete(LinkList &L, int mink, int maxk) {
   p=L->next; //首元结点
   while (p && p->data<=mink)
    { //查找第一个值>mink的结点
		pre=p;p=p->next; 
	} 
   if(p) 
	{
		while(p&&p->data<maxk)  
			p=p->next; // 查找第一个值 ≥maxk的结点
      	q=pre->next;pre->next=p;  // 修改指针
      	while (q!=p) 
        { 
			s=q->next;  delete q;  q=s; 
		} // 释放结点空间
   }
}

9已知p指向双向循环链表中的一个结点,其结点结构为data、prior、next三个域,写出算法change(p),交换p所指向的结点和它的前缀结点的顺序。

[题目分析]

知道双向循环链表中的一个结点,与前驱交换涉及到四个结点(p结点,前驱结点,前驱的前驱结点,后继结点)六条链。

[算法描述]

void  Exchange(LinkedList p)
{//p是双向循环链表中的一个结点,本算法将p所指结点与其前驱结点交换。
	 q=p->llink;
	 q->llink->rlink=p; //p的前驱的前驱之后继为p
	 p->llink=q->llink; //p的前驱指向其前驱的前驱。
	 q->rlink=p->rlink; //p的前驱的后继为p的后继。
	 q->llink=p; //p与其前驱交换
	 p->rlink->llink=q; //p的后继的前驱指向原p的前驱
	 p->rlink=q; //p的后继指向其原来的前驱
}

10已知长度为n的线性表A采用顺序存储结构,请写一时间复杂度为O(n)、空间复杂度为O(1)的算法,该算法删除线性表中所有值为item的数据元素。

[题目分析]

在顺序存储的线性表上删除元素,通常要涉及到一系列元素的移动(删第i个元素,第i+1至第n个元素要依次前移)。本题要求删除线性表中所有值为item的数据元素,并未要求元素间的相对位置不变。因此可以考虑设头尾两个指针(i=1,j=n),从两端向中间移动,凡遇到值item的数据元素时,直接将右端元素左移至值为item的数据元素位置。

[算法描述]

void  Delete(ElemType A[],int n)
{//A是有n个元素的一维数组,本算法删除A中所有值为item的元素。
	i=1;j=n;//设置数组低、高端指针(下标)。
	 while(i<j)
	   {
		   while(i<j && A[i]!=item)i++;//若值不为item,左移指针。
		    if(i<j)
				while(i<j && A[j]==item)
				j--;//若右端元素为item,指针左移
		    if(i<j)
				A[i++]=A[j--];
		}
}
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构练习题-算法设计题-线性表 的相关文章

  • 使用Kinect2作为Oculus游戏应用的输入设备

    注 文章写于2015年8月 眼下VR游戏Demo已经完结 所以把上一次预研的一些经验分享出来 希望对大家有所帮助 背景 初接触Oculus时 从网上下载了一大堆的Demo来体验 可是 操作体验大都比較差 特别是FPS类 这也让我们意识到 对
  • BMP转JPG(法二)RGB数据经过YUV交织

    转载请标明是引用于 http blog csdn net chenyujing1234 欢迎大家拍砖 源码下载地址 http download csdn net detail chenyujing1234 4441643 编译平台 VS20
  • ORACLE not available如何解决

    出现Oracle不可用可以一般情况下有两种办法解决 1 先关闭数据库 在打开数据库 SQL gt shutdown immediate SQL gt startup open 先用这种方式看看问题解决了没有 如果没有再用第二种办法试试 2

随机推荐

  • svn服务器 系统重装恢复吗,请教一下好不好把svn版本库还原到以前的版本?

    1 Linux系统安装svn服务 yuminstall subversion2 新建一个目录用于存储SVN所有文件 mkdir p cbroot svnserver cbweb3 在上面创建的文件夹中为项目project 1 创建一个版本仓
  • 操作系统 虚拟存储器的概念

    虚拟存储器 程序装入内存时可能会出现如下问题 程序太大 要求的空间超出了内存总容量 有大量作业要求运行 但内存不能容下所有作业 常规存储器管理方式的特征 一次性 要求作业全部装入内存才能运行 驻留性 许多不用或暂时不用的程序占用了大量内存空
  • linux命令strings

    linux命令strings 其man信息如下 strings 1 GNU Development Tools strings 1 NAME strings 显示文件中的可打印字符 总览 SYNOPSIS strings a all f p
  • 二维线段树【模板——给出对应注释】

    闲话少说 直接看注释反而会更容易读懂这段二维线段树的模板 include
  • elasticsearch启动报错:master not discovered yet

    通过命令启动 bin elasticsearch E node name hotnode E cluster name geektime E path data hot data E node attr my node type hot 报
  • 违反 GPL 协议赔偿 50 万,国内首例!

    整理 祝涛 出品 CSDN ID CSDNnews 近日 一起关于GPL版权纠纷案裁判文书公示 在一审中 法院指出GPL 3 0协议是一种民事法律行为 具有合同性质 可认定为授权人与用户间订立的著作权协议 属于我国 合同法 调整的范围 来源
  • C++ Primer阅读笔记--数组的使用

    1 理解复杂的数组声明 阅读复杂数组声明时 建议由内向外阅读 int ptrs 10 ptrs是一个含有10个整型指针的数组 int refs 10 错误 不存在引用的数组 int Parray 10 arr Parray指向一个含有10个
  • Qt之TCP心跳包

    Qt之TCP心跳包 当Qt作为客户端程序 而服务器需要监控客户端的在线状态时 就需要Qt端发送心跳包 心跳包可以是TCP也可以是UDP 这里介绍TCP心跳包的实现方法 心跳包通常要单开一个线程 在进程运行的过程中一直执行 代码示例 h文件
  • element-ui —Cascader 级联选择器(选中方式处理)

    目前Vue Element的 el cascader 级联选择器 多选或者选择任意一级 需要点击左侧的checkbox才能选中 目标 点击label选中 已选中状态再次点击label取消选中 有两种方式实现 通过添加点击事件 通过css样式
  • 企业微信第三方应用Demo源码

    第三方应用Demo源码 qywx third java qywx third java企业微信开发指南https github com liyuexi qywx guide企业微信开发第三方应用开发视频 https mp weixin qq
  • vue实现滚动监听,锚点定位,导航高亮

  • matlab双立方插值法_双三次插值(bicubic interpolation)原理及MATLAB源码实现

    双三次插值具体实现 clc clear fff imread E Documents BUPT DIP 图片 lena bmp ff rgb2gray fff 转化为灰度图像 mm nn size ff 将图像隔行隔列抽取元素 得到缩小的图
  • pikachu靶场记录之暴力破解-包括带token的密码猜解

    说明 pikachu是一个免费的php靶场 类似于dvwa 从github下载对应的项目 解压缩并放到phpstudy的www目录下即可 在phpstudy软件中开启apache mysql 访问首页 192 168 10 150 pika
  • Gitee在大数据中心的使用

    在本地主机或者可以VSCode直接连接可视化的服务器上 1 首先在gitee新建一个带有develop分支的仓库 2 在自己的主机 e g server 1 3 上git clone下来 例如 git clone git gitee com
  • Flutter ListView详解

    ListView详解 ListView常用构造 ListView ListView 默认构建 效果 ListView ListTile ListTile 属性 ListTile 使用 效果 ListView builder builder属
  • C# combobox绑定数据源(datasource)

    1 绑定数据源 1 1数据源为dataTable DataTable dt new DataTable 显示的数据 ComBox1 DisplayMemeber name name为DataTable的字段名 隐藏的数据 对于多个数据 可以
  • 左连接(LEFT JOIN)无法返回主表所有行的解决方法

    需求 在业务员管理客户页面 需要展示所有客户信息 并且按客户的最近下单次数进行排序 第一次写的代码如下
  • Vue 2 升级Vue3 ,并且使用vsCode 搭建Vue3 开发环境

    Vue 2 升级Vue 3 版本详细步骤 第一 使用快捷键win R 打开cmd 命令窗口 第二 查看当前电脑运行的vue 版本 请使用如下指令 vue V vue Version 卸载目前vue版本 输入如下指令 npm uninstal
  • JAVA常用的七种设计模式

    学习设计模式之前 我们先要了解一下设计模式的怎么来的 对于设计人员 特别是开发人员吗 往往受限于眼界或经验不能够体会到设计原则的实用性 或者在处理具体问题时 不知道如何把设计原则应用到到设计和代码 因此产生了 模式 随着参与的项目越来越多
  • 数据结构练习题-算法设计题-线性表

    算法设计题 1 将两个递增的有序链表合并为一个递增的有序链表 要求结果链表仍使用原来两个链表的存储空间 不另外占用其它的存储空间 表中不允许有重复的数据 题目分析 合并后的新表使用头指针Lc指向 pa和pb分别是链表La和Lb的工作指针 初