线条合并算法
① 空间线段对求交算法
下面先介绍一种空间线段对求交算法:
图6.5 界线相交特性
三维地质建模方法及程序实现
空间两条线段的求交运算是三维地质建模中使用频率最高、算法最简单,同时也是最容易出现计算误差,并导致后续建模失败的数值运算之一。导致计算失败的主要原因是计算精度与浮点数问题。例如,有3条线段,两两之间的交点距离非常近但不重合,如果保持3个交点不变就会降低后续建模中曲面网格的质量;如果降低精度要求,将3个交点合并成一点,就会影响与其他线段的相交关系。另外,浮点数问题在线段平行判断、三点共线判断、四点共面判断都会遇到。在处理这类问题时,可以采用一个原则,即先精后粗,也就是说在线段对求交时尽量精确,等所有线段对求交结束后可以对距离很近的点进行合并处理。
② 界线的求交算法
当需要进行求交运算的界线较少,且每条界线上的线段也不多时,逐一对分别来自两条界线上的线段进行求交运算是可行的。但是,当界线很多时,这种求交方法将花费大量计算时间,效率十分低下。为此,本书将介绍一种算法:先利用网格定位,尽可能排除不可能相交的线段对,然后逐一对可能相交的线段对进行求交运算。该方法的具体步骤如下:
(1)确定界线矩形包围盒。将所有界线上的所有结点按坐标进行排序,找到最小与最大的三维坐标(xmin,ymin,zmin)与(xmax,ymax,zmax),作为矩形包围盒的角点坐标。
(2)矩形包围盒的网格划分。以一定的间距,将包围盒划分成规则六面体格网,3个方向的间距可以不同,也可以相同。
(3)界线的网格定位,即确定每条界线上的每条线段与哪些网格单元相交,并将与某个网格单元相交的线段记录在该单元的相交线段集上。线段与网格单元的相交判断可以根据线段的端点坐标直接定位。
(4)组建可能相交的线段对。在每个格网单元中,将来自不同界线的线段进行组对,并删除重复出现的线段对。
(5)线段对求交运算。
(6)结点的统一编排。将原有界线上的结点、界线的交点按坐标进行统一排序,按一定的阈值合并距离很近的结点,然后重新设置界线与新结点集中结点的关系。
(7)简单弧的划分。将每条界线划分成若干简单弧,保证每条简单弧是唯一的,并且确保简单弧上除端点以外的内部点不被其他简单弧共享。简单弧划分方法见第7章线框架生成方法。
③ 试写一个算法合并这两个线性链表为一个线性链表。在线等急!!过程截图,要应用结果程序文件。
#include<iostream>
usingnamespacestd;
structtagClass1
{
tagClass1*pNext;
};
intCombineList(tagClass1*pListDest,tagClass1*pListSrc);
voidmain()
{
tagClass1*ptag1Head=NULL;
tagClass1*ptag2Head=NULL;
//中间省略链表赋值过程
CombineList(ptag1Head,ptag2Head);
}
intCombineList(tagClass1*pListDest,tagClass1*pListSrc)
{
if(NULL!=pListDest&&NULL!=pListSrc)
{
tagClass1*pTemp=pListDest;
while(NULL!=pTemp->pNext)
{
pTemp=pTemp->pNext;
}
tagClass1*pTemp2=pListSrc;
while(NULL!=pTemp2)
{
pTemp->pNext=pTemp2->pNext;
}
pTemp->pNext=NULL;
return1;
}
return0;
}
④ 数据结构如何合并两个子图
一种方法可以用hash法 也就是把子图G1的结点先存进hash中 然后G2所有结点依次进行hash查找 如果找到 证明该结点是两个图公共结点 把他们的邻接表合并 这样可以得到所有结点的邻接表 输出即可
⑤ 我是一名计算机菜鸟,下面是数据结构算法2.1合并线性表,错误百出,望高手指正修改,不要求用新方法,谢谢
不得不承认你是菜鸟。你的程序没法改。缺很多东西。估计你是从《数据结构》或者类似的书上直接抄的吧?那都是伪码,不是真正的C++程序。像你这个,ListLength、ListInsert、LocateElem等主要函数都没有定义,能直接用吗?建议楼主先去学好C和C++,再来学习这类课程,否则你永远学不会。
⑥ 试写一个算法,将两个有序线性表合并成一个有序线性表。
void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc)
{
//已知单链线性表La和Lb的元素按非递减排列
//归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列
AH=La;BH=Lb;CH=Lc;
pa=AH_next;pb=BH_next;
CH=pc=AH;//用La的头结点作为Lc的头结点
while(pa&&pb)
{
if(pa->data<=pb->data){
pc-<next=pa;pc=pa;pa=pa->next;
}
elsr {pc->next=pb;pc=pb;pb=pb->next;}
}
pc->next=pa?pa:pb;//插入剩余段
free(BH);//释放Lb的头结点
}//MergeList_L
⑦ 炒股的通达信软件如何把20,30,60日均线和布林线合并设置为三条线
没明白你说的意思,首先布林线的中线就是20日均线,布林上轨下轨是20日均线加减自身两倍标准差算出来的,再加上30日和60日均线,一共5条线怎么合并成3条啊,之间的算法没什么关系啊。
⑧ 设线性表A=(a1,a2,…,am),B=(b1,b2,…,bn),试写一个按下列规则合并A,B为线性表C的算法,即使得
估计你是写错了LinkList pa,pb,qa,qb; 应该是 LinkList *pa,*pb,*qa,*qb;
Status ListMerge_L(LinkList &A,LinkList &B,LinkList &C)
{
LinkList *pa,*pb,*qa,*qb;
pa=A->next; //pa指向A的第二个节点,估计第一个节点没数据
pb=B->next; //pb指向B的第二个节点
C=A;
while(pa&&pb){ //这个while就是循环啊,直到pa或pb指向NULL
qa=pa;
qb=pb;
pa=pa->next; //pa指向下一个节点
pb=pb->next; //pb指向下一个节点
qb->next=qa->next; //创建新链表在qb节点后面插入qa节点
qa->next=qb; //qa后面插入qb节点
}
//if(!pa)qb->next=pb; //应该写错了吧。
//pb=B;
if(!pa)qb->next=pa; //如果B比A短,B最后一个节点的next指针指向A剩下的
if(!pb)qa->next=pb; //如果A比B短,A最后一个节点的next指针指向B剩下的
free(pb);
return OK; //OK应该是你前面宏定义的吧,估计是#define OK 1
}
⑨ 求归并排序算法!
归并排序。
1.这里,在把数组暂时复制到临时数组时,将第二个子数组中的顺序颠倒了一下。这样,两个子数组从两端开始处理,使得他们互相成为另一个数组的“检查哨”。 这个方法是由R.Sedgewick发明的归并排序的优化。
2.在数组小于某一阀值时,不继续归并,而直接使用插入排序,提高效率。这里根据Record的结构,将阀值定位 16。
#define THRESHOLD 16
typedef struct _Record{
int data; //数据
int key; //键值
}Record;
//供用户调用的排序 函数
void Sort(Record Array[], Record TempArray, int left, int right){
TwoWayMergeSort(Array, TempArray, left, right);
}
//归并排序
void TwoWayMergeSort(Record Array[], Record TempArray[],
int left, int right)
{
if(right <= left) return; //如果只含一个元素,直接返回
if( right-left+1 ){ //如果序列长度大于阀值,继续递归
int middle = (left + right)/2;
Sort(Array, TempArray, left, middle); //对左面进行递归
Sort(Array, TempArray, left, right, middle); //对右面进行递归
Merge(Array, TempArray, left, right, middle); //合并
}
else{
//如果序列长度小于阀值,采用直接插入排序,达到最佳效果
ImproveInsertSorter(&Array[left], right-left+1);
}
}
//归并过程
void Merge(Record Array[], Record TempArray[],
int left, int right, int middle)
{
int index1, index2; //两个子序列的起始位置
int k;
复制左边的子序列
for(int i=1; i<=middle; i++){
TempArray[i] = Array[i];
}
//复制右边的子序列,但顺序颠倒过来
for(int j=1; j<=right-middle; j++){
TempArray[right-j+1] = Array[j+middle];
}
//开始归并
for(index1=left, index2=right, k=left; k<=right; k++){
if(TempArray[index1].key<TempArray[index2].key){
Array[k] = TempArray[index++];
}
else{
Array[k] = TempArray[index2--];
}
}
}
//当长度小于阀值时 使用的直接插入排序的代码
void ImproveInsertSorter(Record Array[], int size){
Record TempRecord; //临时变量
for(int i=1; i<size; i++){
TempRecord = Array[i];
int j = i-1;
//从i开始往前寻找记录i的正确位置
while(j>=0 && TempRecord.key<Array[j].key){
Array[j+1] = Array[j];
j = j-1;
}
Array[j+1] = TempRecord;
}
}
终于敲完了。。。 第一次回答问题, 只是觉得好玩`