怎么将两个顺序存储的有序表合并成一个有序表?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么将两个顺序存储的有序表合并成一个有序表?相关的知识,希望对你有一定的参考价值。
具体代码如下:
#include<stdio.h>
#include<stdlib.h>
#define MAX 40
typedef struct
int data[MAX];
int length;
LinkList;
void Initial_List(LinkList * &l,int n)//初始化顺序表
int i=0;
l=(LinkList *)malloc(sizeof(LinkList));
l->length = 0;
for(;i<n;i++)
scanf("%d",l->data+i);
l->length = n;
void Link(LinkList *l1,LinkList *l2,LinkList * &l3)//连接顺序表
int i,j;
l3=(LinkList *)malloc(sizeof(LinkList));
l3->length = l1->length + l2->length;
for(i=0;i<l3->length;i++)
if(i<l1->length)
l3->data[i] = l1->data[i];
else
l3->data[i] = l2->data[i%(l1->length)];
for(i=0;i<l3->length;i++)
for(j=i+1;j<l3->length;j++)
if(l3->data[i]>l3->data[j])
int temp=l3->data[i];
l3->data[i]=l3->data[j];
l3->data[j]=temp;
void Disp_List(LinkList *l)
int i=0;
printf("output:\\n");
for(;i<l->length;i++)
printf("%d ",l->data[i]);
printf("\\n");
int main()
LinkList *l1,*l2,*l3;
int n;
printf("请输入第一个序列的元素个数:\\n");
scanf("%d",&n);
printf("请输入第一个序列的所有元素:\\n");
Initial_List(l1,n);
printf("请输入第二个序列的元素个数:\\n");
scanf("%d",&n);
printf("请输入第二个序列的所有元素:\\n");
Initial_List(l2,n);
Link(l1,l2,l3);
Disp_List(l3);
return 0;
编写算法,将两个非递减有序顺序表A和B合成一个新的非递减有序顺序表C。
已知顺序表A和B的元素个数分别为m,n。其中顺序表采用动态分配内存空间,其定义如下:
typedef struct
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量
Sqlist;
*/
参考技术A 代码有错…还没法合并 参考技术B 具体代码如下:#include<stdio.h>
#include<stdlib.h>
#define MAX 40
typedef struct
int data[MAX];
int length;
LinkList;
void Initial_List(LinkList * &l,int n)//初始化顺序表
int i=0;
l=(LinkList *)malloc(sizeof(LinkList));
l->length = 0;
for(;i<n;i++)
scanf("%d",l->data+i);
l->length = n;
void Link(LinkList *l1,LinkList *l2,LinkList * &l3)//连接顺序表
int i,j;
l3=(LinkList *)malloc(sizeof(LinkList));
l3->length = l1->length + l2->length;
for(i=0;i<l3->length;i++)
if(i<l1->length)
l3->data[i] = l1->data[i];
else
l3->data[i] = l2->data[i%(l1->length)];
for(i=0;i<l3->length;i++)
for(j=i+1;j<l3->length;j++)
if(l3->data[i]>l3->data[j])
int temp=l3->data[i];
l3->data[i]=l3->data[j];
l3->data[j]=temp;
void Disp_List(LinkList *l)
int i=0;
printf("output:\\n");
for(;i<l->length;i++)
printf("%d ",l->data[i]);
printf("\\n");
int main()
LinkList *l1,*l2,*l3;
int n;
printf("请输入第一个序列的元素个数:\\n");
scanf("%d",&n);
printf("请输入第一个序列的所有元素:\\n");
Initial_List(l1,n);
printf("请输入第二个序列的元素个数:\\n");
scanf("%d",&n);
printf("请输入第二个序列的所有元素:\\n");
Initial_List(l2,n);
Link(l1,l2,l3);
Disp_List(l3);
return 0;
合并排序——二路合并排序
什么是合并排序:
合并排序就是将两个或多个有序表合并成一个有序表,将两个有序表合并成一个有序表称为二路合并
算法描述 :
二路合并排序的基本思想是:对于两个有序表合并,初始时, 把含有n个结点的待排序序列看作有n个长度为1的有序子表所组成,将它们依次两两合并,得到长度为2的若干有序子表,再对这些子表进行两两合并,一直重复到长度为n,排序完成。
合并排序过程:
初始序列:
二路合并排序需要较大的辅助空间,辅助空间的大小与待排序序列一样多。
(1)将14个原数据看成14个长度为1的有序表(只有一个数据,肯定是有序的)
(2)将14个有序表两两合并,即将1,2合并3,4合并.....如果后面有单独一个元素的,就单独放在那里,直接进入下一遍合并
(3)经过第一遍的合并,得到长度为2的有序表序列,再将这些长度为2的有序表序列进行两两合并。
(4)经过第二遍合并之后,得到长度为4的有序表的序列,再将这些长度为4的有序表进行两两合并。
(5) 经过上面的合并,得到长度为8的有序表,再将这些长度为8的有序表进行两两合并。
合并相邻有序表 :
如果需合并的两个有序表分别保存于数组A中,其中一个序列保存在下标s~m的数组元素中,另一个序列保存在下标从m+1~n的数组元素中。合并把结果保存在数组R中。用变量i,j分别指向两个系列中需要比较的元素,变量k指向数组R中的序号,表示下一个要保存的数据的位置。
(1) 取第1个系列的第i个元素A[i],与第2个系列的第1个元素比较A[j]。
(2) 若A[i]<=A[j],则将A[i]复制到R[k]中,使i和k分别增加1.
(3)若A[i]>A[j],则将A[j]复制到R[k]中,使j和k分别增加1
(4)重复步骤1~3,直到一个序列复制完为止。
(5)将另一个序列中比较的数据复制到R的剩余位置。
//a[low...mid]和a[mid+1,high] 而b[low...high] void Merge(int a[],int b[],int low,int mid,int high){ int i=low; int j=mid+1; int k=low;
while(i<=mid && j<=high){ if(a[i]<=a[j]){ b[k++]=a[i++]; }else{ b[k++]=a[j++]; } } private static void merge(int a[],int temp[],int low,int mid,int high){ int i=low; int j=mid+1; int k=0;
while(i<=mid && j<=high) { if(a[i]<=a[j]) { temp[k++]=a[i++]; }else { temp[k++]=a[j++]; } } while(i<=mid) { temp[k++]=a[i++]; } while(j<=high) { temp[k++]=a[j++]; } k = 0; // 将temp中的元素全部拷贝到原数组中 while (low <= high) { a[low++] = temp[k++]; } } |
归并排序:
(1) 二路归并排序将a[low...high]中的记录归并排序后放入temp[low...high]中。当序列长度等于1时,递归结束,否则:
a) 将当前序列一分为二,求出分裂点mid=(low+high)/2
b) 对子序列a[low..mid]递归,进行归并排序,结果放入temp[low...mid]
c) 对子序列a[mid+1,high],进行归并排序,结果放入temp[mid+1,high]
d) 调用Merge将有序的两个子序列a[low..mid]与a[mid+1,high]归并为一个有序的序列temp[low...high]
/** * sort */ public static void sort(int a[],int temp[],int low,int high) { if(low<high) { int mid=(low+high)/2; sort(a,temp,low,mid); sort(a,temp,mid+1,high); merge(a,temp,low,mid,high); } } |
算法实例:
public class MergeSort { /** * 相邻有序子序列进行合并 * a[low...mid] a[mid+1,high] */ private static void merge(int a[],int temp[],int low,int mid,int high){ int i=low; int j=mid+1; int k=0;
while(i<=mid && j<=high) { if(a[i]<=a[j]) { temp[k++]=a[i++]; }else { temp[k++]=a[j++]; } } while(i<=mid) { temp[k++]=a[i++]; } while(j<=high) { temp[k++]=a[j++]; } k = 0; // 将temp中的元素全部拷贝到原数组中 while (low <= high) { a[low++] = temp[k++]; } }
public static void sort(int a[],int temp[],int low,int high) { if(low<high) { int mid=(low+high)/2; sort(a,temp,low,mid); sort(a,temp,mid+1,high); merge(a,temp,low,mid,high); } } public static void sort(int []arr){ int []temp = new int[arr.length];//在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间 sort(arr,temp,0,arr.length-1); } public static void main(String[] args) { int arr[]= {56,41,26,32,55,75,2,63,12,19,58,77,34,95}; sort(arr); System.out.println("排序结果:"+Arrays.toString(arr));
/* 测试,合并有序子序列 int arr[]= {1,3,5,2,4,6}; int temp[]=new int[arr.length]; merge(arr, temp, 0, 2, arr.length-1);
System.out.println("排序结果:"+Arrays.toString(arr)); System.out.println("排序结果:"+Arrays.toString(temp)); */ } } |
以上是关于怎么将两个顺序存储的有序表合并成一个有序表?的主要内容,如果未能解决你的问题,请参考以下文章