数据结构题集-第二章-线性表-有序线性表的交集

ops/2024/11/17 5:44:45/

有序线性表的交集

  • 说明
  • 2.25 假设两个元素依值递增有序排列的线性表A和B

说明

  • 本文参照严蔚敏《数据结构(C语言版)题集》一书中包含的问答题和算法设计题目,提供解答和算法的解决方案。
  • 请读者在自己已经解决了某个题目或进行了充分的思考之后,再参考本解答,以保证复习效果。
  • 由于作者水平所限,本解答中一定存在不少这样或者那样的错误和不足,希望读者们在阅读中多动脑、勤思考,争取发现和纠正这些错误,写出更好的算法来。

2.25 假设两个元素依值递增有序排列的线性表A和B

分别表示两个集合,
且同一表中的元素值各不相同,
现要求另辟空间构成一个线性表C,
其元素为A和B中元素的交集,
且表C中的元素也依值递增有序排列。
试对线性表编写求C的算法

解:
争取作最少比较就可以从两个递增线性表中提取仍然有序的交集:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10#define MAX_TEST_LENGTH 20
#define MAX_TEST_ELEM 20
typedef int ElemType;
typedef struct{ElemType *elem; // 存储空间基址int length; // 当前长度int listsize; // 当前分配的存储容量
} SqList; // 顺序表类型
typedef struct LNode{ElemType data;struct LNode *next;
} LNode, *LinkList; // 线性链表类型Status InitList_Sq(SqList *pL){// 构造一个空的线性表(*pL).elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));if(!(*pL).elem) exit(OVERFLOW); // 存储分配失败(*pL).length = 0; // 空表长度为0(*pL).listsize = LIST_INIT_SIZE; // 初始存储容量return OK;
}// InitList_SqStatus ListInsert_Sq(SqList *pL, int i, ElemType e){// 在顺序线性表L中第i个位置之前插入新的元素e// i的合法值范围:[1,ListLength_Sq(L)+1]if(i<1 || i>((*pL).length+1)) return ERROR; // i值不合法if((*pL).length>=(*pL).listsize){ // 当前存储空间已满,增加分配ElemType *newbase = (ElemType *)realloc((*pL).elem,((*pL).listsize+LISTINCREMENT)*sizeof(ElemType));if(!newbase) exit(OVERFLOW); // 存储分配失败(*pL).elem = newbase; // 新基址(*pL).listsize += LISTINCREMENT; // 增加存储容量}ElemType *p = NULL;ElemType *q = &((*pL).elem[i-1]); // q为插入位置for(p=&((*pL).elem[(*pL).length-1]);p>=q;--p) *(p+1) = *p; // 插入位置及之后的元素右移*q = e; // 插入e++((*pL).length); // 表长增1return OK;
}// ListInsert_SqStatus FreeList_Sq(SqList *pL){// 释放线性表if(NULL!=(*pL).elem){free((*pL).elem);return OK;}else{return ERROR;}
}// FreeList_Sqint InsertOrderSqList(SqList *pL,int x){//把x插入递增有序表pL中,并返回插入的位置(数组下标)int i;if((*pL).length+1>(*pL).listsize) return OVERFLOW;(*pL).length++;for(i=(*pL).length-1;(*pL).elem[i]>x&&i>=0;i--)(*pL).elem[i+1]=(*pL).elem[i];(*pL).elem[i+1]=x;return i+1;
}//InsertOrderSqList int cmp(const void *x,const void *y){// qsort函数需要调用的比较函数ElemType *a=(ElemType *)x; ElemType *b=(ElemType *)y;return (*a-*b);
}void intersect_set(SqList A,SqList B,SqList *pC){//元素递增排列的线性表A和B中元素交集合并存入C中,仍保持有序int i,j,k;i=j=k=0;while(i<A.length&&j<B.length){if(A.elem[i]<B.elem[j]) i++;else if(A.elem[i]>B.elem[j]) j++;else{pC->elem[k++]=A.elem[i];pC->length++;i++;j++;}}
}void sorted_list_to_set(SqList *pL){//在顺序线性表中去除重复元素,成为集合int i,j,k,d;for(i=0;i<pL->length;i++){k=i;for(j=i+1;(j<pL->length)&&(pL->elem[j]==pL->elem[i]);j++);if(j>i+1){d=j-i-1;while(j<pL->length){pL->elem[++k]=pL->elem[j++];}pL->length -= d;}}
}void display_list(SqList L){int i;for(i=1;i<=L.length;i++){printf("%3d.%d\t",i-1,L.elem[i-1]);if(i%7==0) putchar('\n');}
}Status rand_create_sorted_sets(SqList *pA, SqList *pB){int pos,dupli_rand_count,dupli_rand_num;time_t t;int count;srand((unsigned)time(&t)); //初始化随机数发生器count = rand()%MAX_TEST_LENGTH;while(count--){dupli_rand_count=rand()%10;dupli_rand_num=rand()%MAX_TEST_ELEM;while(dupli_rand_count--){if(OK!=ListInsert_Sq(pA,1+rand()%((*pA).length+1),dupli_rand_num))return ERROR; // 随机找一个合法位置插入新随机元素}}qsort((*pA).elem,(*pA).length,sizeof(ElemType),cmp);//printf("\nSqList A:\n");//display_list(*pA);sorted_list_to_set(pA);printf("\nA:\n");display_list(*pA);count = rand()%MAX_TEST_LENGTH;while(count--){dupli_rand_count=rand()%10;dupli_rand_num=rand()%MAX_TEST_ELEM;while(dupli_rand_count--){if(OK!=ListInsert_Sq(pB,1+rand()%((*pB).length+1),dupli_rand_num))return ERROR; // 随机找一个合法位置插入新随机元素}}qsort((*pB).elem,(*pB).length,sizeof(ElemType),cmp);//printf("\nSqList B:\n");//display_list(*pB);sorted_list_to_set(pB);printf("\nB:\n");display_list(*pB);return OK;
}int main(){ElemType x;SqList La,Lb,Lc;if(OK!=InitList_Sq(&La)) return ERROR;if(OK!=InitList_Sq(&Lb)) return ERROR;if(OK!=InitList_Sq(&Lc)) return ERROR;if(OK!=rand_create_sorted_sets(&La,&Lb)) return ERROR;intersect_set(La,Lb,&Lc);printf("\nC:\n");display_list(Lc);if(OK==FreeList_Sq(&La))printf("\nFree SqList A success!\n");if(OK==FreeList_Sq(&Lb))printf("\nFree SqList B success!\n");if(OK==FreeList_Sq(&Lc))printf("\nFree SqList C success!\n");return 0;
}

测试数据基本符合题目的要求,其中去重的算法sorted_list_to_set已经做到最简。


http://www.ppmy.cn/ops/134344.html

相关文章

集群搭建高可用

contos7.9 部署3节点 hadoop3.4 高可用集群 contos7.9 部署3节点 hadoop3.4 高可用集群环境信息Hadoop与Zookeeper的版本对应关系服务器角色分配使用端口服务器配置配置免密登录服务器配置初始化 init_server.sh配置主机名映射所有节点配置 hosts文件 hadoop 安装环境配置下载安…

桥梁缺陷YOLO免费数据集分享 – 6308张已标注8类缺陷图像

本次分享的是一套高质量的桥梁缺陷YOLO数据集&#xff0c;主要以混凝土桥梁为对象&#xff0c;包含了大量真实的桥梁缺陷图像&#xff0c;旨在支持桥梁检测、结构健康监测以及缺陷自动识别的相关研究与应用。该数据集经过精心标注&#xff0c;包含了8种主要的桥梁缺陷类别&…

UG Motion学习笔记2【正解 反解】

使用软件&#xff1a;SP Model NX12.0 Robot Arm的正解&#xff1a; &#xff08;先添加关节驱动&#xff0c;进行正解。再添加连杆驱动&#xff0c;进行反解。&#xff09; 直接点击_step.prt零件打开。一共7个构件&#xff0c;6个运动副&#xff08;圆片&#xff0c;转角&…

矩阵起源入选IDC《RAG与向量数据库市场前景预测》报告

近日&#xff0c;国际知名市场研究机构IDC发布了《RAG与向量数据库市场前景预测》报告&#xff0c;分析了检索增强生成&#xff08;RAG&#xff09;和向量数据库市场的发展趋势和技术走向。报告中提到&#xff0c;生成式AI的大规模应用使向量数据库成为重要的基础设施&#xff…

Vue中的导航守卫有哪三种?分别有什么作用

Vue Router中的导航守卫主要分为三种&#xff1a;全局前置守卫、全局解析守卫和全局后置钩子。每种守卫都有其特定的作用&#xff0c;以下是对这三种导航守卫的详细解释&#xff1a; 1. 全局前置守卫&#xff08;beforeEach&#xff09;作用&#xff1a; 全局的权限验证&…

element plus的表格内容自动滚动

<el-table:data"tableData"ref"tableRef"borderstyle"width: 100%"height"150"><el-table-column prop"date" label"名称" width"250" /><el-table-column prop"name" label&…

版本控制-Git

版本控制 一、概念 版本控制是管理修改的艺术指对软件开发过程中各种程序代码、配置文件及说明文档等文件的变更管理是软件管理配置的核心思想之一 二、好处 优雅的备份&#xff1a; 本地和服务器均保存备份文件&#xff0c;当本地出现问题时可以通过服务器修复 多人并行开发&…

计算器上的MC、MR、M+、M—、CE是什么意思?

在计算器中&#xff0c; MC键叫做memory clear&#xff0c;中文 清除存储&#xff0c;是一个清除寄存器中存储数字的指令。 MS键叫做memory save&#xff0c;中文 存入存储。 而MR键&#xff0c;则是一个读取原先存储在寄存器中的数字的指令。 M键指将当前数值存入寄存器以…