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

ops/2024/11/14 6:25:01/

有序单链表的交集

  • 说明
  • 2.26 假设两个元素依值递增有序排列的单链表A和B

说明

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

2.26 假设两个元素依值递增有序排列的单链表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 PASS 2
#define MAX_TEST_LENGTH 8
#define MAX_TEST_ELEM 20
typedef int ElemType;typedef struct SLNode{ // 结点类型ElemType data;struct SLNode *next;
} LNode, *Link;typedef struct{ // 链表类型Link head,tail; // 分别指向线性链表中的头结点和最后一个结点int len; // 指示线性链表中数据元素的个数
} LinkList;Status MakeNode(Link *pp,ElemType e){// 分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR*pp=(Link)malloc(sizeof(LNode));if(!*pp) return ERROR;(*pp)->data=e;(*pp)->next=NULL;return OK;
}void FreeNode(Link p){// 释放p所指结点if(NULL!=p){printf("free [%lld]=%d\n",(long long)p,p->data);free(p);}
}Status InitList(LinkList *pL){// 构造一个空的线性链表LLink p;if(ERROR==MakeNode(&p,0)) return ERROR;(*pL).head=p;(*pL).tail=NULL;(*pL).len=0;return OK;
}Status ClearList(LinkList *pL){// 将线性表L重置为空表,并释放原链表的结点空间Link p;if(NULL==pL) return ERROR;if(NULL!=(*pL).head) p=((*pL).head)->next;while(p){((*pL).head)->next=p->next;FreeNode(p);p=((*pL).head)->next;}(*pL).tail=NULL;(*pL).len=0;return OK;
}Status DestroyList(LinkList *pL){// 销毁线性链表Lif(ERROR==ClearList(pL)) return ERROR;if(NULL!=(*pL).head) FreeNode((*pL).head);(*pL).head=NULL;return OK;
}void print_list(LinkList L){// 显示链表的内容int c=0;Link p=(L.head)->next;while(p&&c<L.len){printf("->[%d].%d",++c,p->data);p=p->next;}if(L.tail)printf("\n%d elements and tail->[%d].%d\n",L.len,L.len,L.tail->data);elseprintf("\n%d elements and tail->NULL\n",L.len);
}Status InsOrderAsc(LinkList *pL,Link s){// 已知线性链表的尾结点,将s所指结点插入后保持链表有序// 如果插入到表尾,尾指针发生变化// 线性链表的元素个数加1Link p;if(NULL==pL||NULL==s) return ERROR;p=pL->head;while(p->next && (p->next->data) < (s->data)) p=p->next;s->next=p->next;p->next=s;if(NULL==s->next) pL->tail=s;pL->len++;return OK;
}//InsOrderAscStatus intersect_linked_sets(LinkList A,LinkList B,LinkList *pC){//元素递增排列的单链表A和B中元素交集合并存入单链表C中,仍保持有序Link p,q,r,t;if(NULL==pC) return INFEASIBLE;p=A.head->next;q=B.head->next;r=pC->head;while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else{t=NULL;if(ERROR==MakeNode(&t,p->data)) return ERROR;if(ERROR==InsOrderAsc(pC,t)) return ERROR;p=p->next;q=q->next;}}return OK;
}void sorted_list_to_set(LinkList *pL){//在顺序单链表中去除重复元素Link p,q;if(NULL==pL) return;p=pL->head->next;while(p){q=p->next;while(q&&q->data==p->data){p->next=q->next;FreeNode(q);q=p->next;pL->len--;}pL->tail=p;p=p->next;}
}Status rand_sorted_sets_intersect(LinkList *pA,LinkList *pB,LinkList *pC){Status result;int c,dupli_rand_count,dupli_rand_num;time_t t;Link p;srand((unsigned)time(&t)); //初始化随机数发生器c = rand()%MAX_TEST_LENGTH;while(c--){dupli_rand_count=rand()%10;dupli_rand_num=rand()%MAX_TEST_ELEM;while(dupli_rand_count--){p=NULL;if(ERROR==MakeNode(&p,dupli_rand_num)) return ERROR;if(ERROR==InsOrderAsc(pA,p)) return ERROR;}}printf("\nA:\n");print_list(*pA);sorted_list_to_set(pA);printf("\nLinked set A:\n");print_list(*pA);c = rand()%MAX_TEST_LENGTH;while(c--){dupli_rand_count=rand()%10;dupli_rand_num=rand()%MAX_TEST_ELEM;while(dupli_rand_count--){p=NULL;if(ERROR==MakeNode(&p,dupli_rand_num)) return ERROR;if(ERROR==InsOrderAsc(pB,p)) return ERROR;}}printf("\nB:\n");print_list(*pB);sorted_list_to_set(pB);printf("\nLinked set B:\n");print_list(*pB);result=intersect_linked_sets(*pA,*pB,pC);if(result==OK){printf("\nIntersect:\n");print_list(*pC);}else{printf("\nError...\n");}return result;
}int main(){LinkList La,Lb,Lc;if(ERROR==InitList(&La)) return ERROR;if(ERROR==InitList(&Lb)) return ERROR;if(ERROR==InitList(&Lc)) return ERROR;if(OK==rand_sorted_sets_intersect(&La,&Lb,&Lc)) printf("\nIntersect success\n");if(OK==DestroyList(&La)) printf("Free La success\n");if(OK==DestroyList(&Lb)) printf("Free Lb success\n");if(OK==DestroyList(&Lc)) printf("Free Lc success\n");return 0;
}

算法思想和上题2.25相似,为了准备测试数据去重的算法和顺序存储有些不同。


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

相关文章

XMLHttpRequest以及Promise对象的使用

AJAX原理 通过[XHR]XMLHttpRequest对象来和服务器进行交互&#xff0c;axios库的底层也是通过XMLHttpRequest来和服务器进行交互&#xff0c;只是将实现细节进行了封装&#xff0c;让操作更加简洁 可以用于某些只需和服务器进行少次交互的静态网站进行使用&#xff0c;减少代…

three.js 杂记

clip&#xff1a; 1&#xff1a; 着色器 #ifdef USE_CLIP_DISTANCE vec4 worldPosition modelMatrix * vec4( position, 1.0 ); gl_ClipDistance[ 0 ] worldPosition.x - sin( time ) * ( 0.5 ); #endif gl_Position projectionMatrix * modelViewMatrix * vec4( positio…

CNN中每一层的权重是一样的么?

在卷积神经网络&#xff08;CNN&#xff09;中&#xff0c;每一层的权重并不是完全相同的&#xff0c;但在同一层内是共享的。具体来说&#xff0c;CNN的权重共享机制是指&#xff1a;在卷积层中&#xff0c;同一卷积核&#xff08;filter&#xff09;在输入图像的不同区域进行…

微擎框架php7.4使用phpexcel导出数据报错修复

在使用微擎社区版时&#xff0c;用phpexcel导出数据&#xff0c;提示错误&#xff0c;经过搜索后得知是php版本问题。 之前一直是用的5.6现在改成了7.4。所以才发现了这个问题。 然后去gitee上看了下微擎官方的代码&#xff0c;好像也没有对这个问题进行修复。 找了下&#…

【蓝桥杯 2021 省 B2】特殊年份

题目描述&#xff1a; 今年是 2021 年&#xff0c;2021 这个数字非常特殊, 它的千位和十位相等, 个位比百位大 1&#xff0c;我们称满足这样条件的年份为特殊年份。 输入 5 个年份&#xff0c;请计算这里面有多少个特殊年份。 输入格式 输入 5 行&#xff0c;每行一个 4 位十…

matlab建模入门指导

本文以水池中鸡蛋温度随时间的变化为切入点&#xff0c;对其进行数学建模并进行MATLAB求解&#xff0c;以更为通俗地进行数学建模问题入门指导。 一、问题简述 一个煮熟的鸡蛋有98摄氏度&#xff0c;将它放在18摄氏度的水池中&#xff0c;五分钟后鸡蛋的温度为38摄氏度&#x…

mysql每日一题(上升的温度,date数据的计算)

日期之间的运算 日期类型的加法运算 data_add(now_data,interval 1 month) select date_add(now(), interval 1 day); -- 加1天 select date_add(now(), interval 1 hour); -- 加1小时 select date_add(now(), interval 1 minute); -- 加1分钟 select date_add(now(), inter…

Scala的Map集合练习

package gxyimport scala.collection.mutableobject Test25 {def main(args: Array[String]): Unit {//可变mapval map1 mutable.Map("123" -> "活着,余华,8888", "234" -> "朝花夕拾,鲁迅,7777", "456" -> &quo…