求无序序列每个元素最接近的值
来源:互联网 发布:淘宝卖家套餐怎么设置 编辑:程序博客网 时间:2024/06/05 16:10
1、问题描述
给一个n个元素的线性表A,对于每个数Ai,找到它之前的数中,和它最接近的数。
即对于每个i,求 Ci = min{ |Ai -Aj | | 1<= j < i}
1.2算法分析
有两种思路可以解决上诉问题:
(1) 遍历整个线性表,对每个元素 A[i] ,遍历 A[0] - A[i-1] , 求出与 A[i] 绝对值最小的元素。这种方法的效率为O(n^2)。
(2)先对线性表 A 进行排序, 将结果构造成双向链表 L 。反向遍历 A,将每个元素 A[i] , 比较 A[i] - A[i-1] 和A[i+1] - A[i] ,取两者中与 A[ i ] 更接近的,即是 A[ i ] 之前的数中与 A[ i ]最接近的。然后 将A[i] 从L中删去。则双向链表中剩下的元素就是 A[i] 前面的元素。这种方法的效率可以达到O(nlogn)。
1.3 算法过程图解
1.4 思路2算法实现
首先,需要的一个双向链表作为辅助,定义双向链表结构如下:
struct LNode{ struct LNode* next; struct LNode* prev; int key;};
给链表添加一些操作,来支持解决问题:
#include <stdio.h>#include <malloc.h>#include "lcl.h"//从数组里创建链表 struct LNode* create_list_from_array( int* array,int array_length){struct LNode* head,*prev_node=NULL,*node;int i=0;for(i=0;i<array_length;i++){node=(struct LNode*)malloc(LEN);node->key=array[i];node->next=NULL;node->prev=prev_node;if(prev_node==NULL) //创建第一个结点时执行 { head=node; }else{ prev_node->next=node; } prev_node=node;}return head;}//求与node结点值最接近的结点,并打印 void get_near(struct LNode* node) {int a=0,b=0,c=0,ab=0,bc=0,near;if(node->prev==NULL&&node->next==NULL) {printf("no other num before %d \n",node->key);return;}if(node->prev==NULL){ printf("brefore and the most nearest %d num is:%d\n",node->key,node->next->key); return;}if(node->next==NULL){ printf("brefore and the most nearest %d num is:%d\n",node->key,node->prev->key); return;}a=node->prev->key;b=node->key;c=node->next->key;ab=b-a;bc=c-b;near=ab>bc?c:a;printf("brefore and the most nearest %d num is:%d\n",node->key,near);}//从链表删除值为n的一个元素 struct LNode* delete_last_n(struct LNode* list,int n){struct LNode* head=list,*node=list,*prev,*curr,*next;while(node!=NULL&&node->key<n){node=node->next;}prev=node->prev;curr=node;next=node->next;get_near(node);if(prev==NULL&&next==NULL){ free(curr); return NULL; }if(prev!=NULL){prev->next=next;}else{list=next;}if(next!=NULL){ next->prev=prev;}else{prev->next=NULL;}free(curr); return list;}
然后,需要一个排序算法对线性表进行排序,这里使用到归并排序:
extern void print_array(int* array,int n);//归并排序 void merge_array(int* array,int p,int q,int r){int l1=q-p+2,l2=r-q+1;int A[l1],B[l2]; //多加 1为最后一个元素赋最大值留着 int i=0,j=0,k=0;for(i=p,j=0;i<=q;i++,j++){A[j]=array[i];}A[j]=MAX_NUMBER;for(i=q+1,j=0;i<=r;i++,j++){B[j]=array[i];}B[j]=MAX_NUMBER;i=0,j=0,k=0;for(k=p;k<=r;k++){if(A[i]>B[j]){ array[k]=B[j]; j++;}else{ array[k]=A[i]; i++;}}}void merge_sort(int* array,int p,int r){ //归并排序,p为计数起点,一般是0,r为数组最后序号,为n-1 if(p<r){ int q=p+(r-p)/2;merge_sort(array,p,q);merge_sort(array,q+1,r); merge_array(array,p,q,r);}}
//初始化并运行程序 void init(int array_length) { int array[array_length],array2[array_length],i=0; struct LNode* list; get_iarray_scf(array,array_length); //获取输入数组 copy_array(array,array2,array_length); //保存初始数组 print_array(array,array_length); //对数组排序 merge_sort(array,0,array_length-1); //将排序结果创建双向链表 list=create_list_from_array(array,array_length); // 从后往遍历输入数组,依次从双向链表删除 for(i=array_length-1;i>=0;--i) { list=delete_last_n(list,array2[i]); }}
附录:
1、代码
2、参考教程
0 0
- 求无序序列每个元素最接近的值
- 求无序数组中三个元素相加与目标数最接近的三元素之和
- 求一个无序数组的子数组, 子数组的和最接近0
- 有两个序列a,b,大小都为n,序列元素的值任意整数,无序
- 有两个序列a,b,大小都为n,序列元素的值任意整数,无序
- 求两个等长升序序列中每个序列取一个元素求和的第K小元素
- 查找最接近的元素
- 查找最接近的元素
- 查找最接近的元素
- 求无序数组的第二小的元素
- 查找无序序列中第i小的元素
- 求无序数组中两元素相加等于特定值的索引
- 求无序数组中三元素相加等于特定值的所有情况
- 求无序数组中四元素相加等于特定值的所有情况
- 求无序数组中第二小的元素
- 有两个序列a,b,大小都为n,序列元素的值是任意整数,无序。
- 有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
- 有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
- PAT-PAT (Advanced Level) Practise 1018. Public Bike Management (30) 【四星级】
- C语言 extern static使用比较
- atoi 等相关函数的用法
- Webpower携手梅花网,打造优雅的SaaS产品服务
- Android开发 模块化编程之引用本地的aar
- 求无序序列每个元素最接近的值
- PL/SQL教程
- tomcat利用setenv对内存的限制和docker中tomcat内存的优雅配置
- iOS开发笔记-tabbar图标设成用户头像
- JAVA方法耗时信息捕捉并日志
- Mapeduce编程八大步骤
- js和jquery获取各种宽度和盖度
- s:url标签使用
- padding和margin两个重要属性的介绍及举例