两路归并排序
链表两路归并
#include<iostream>
#include<assert.h>
using namespace std;
struct node
{
int val;
node * next;
node(int v)
{
val=v;
next=NULL;
}
};
node * merge(node* list1 , node * list2)
{
assert(list1!=NULL&&list2!=NULL);//括号中是希望出现的正确的情况
node * res;
if(list1->val<=list2->val)
{
res=list1;
list1=list1->next;
}
else
{
res=list2;
list2=list2->next;
}
node * p = res;
node *p1 =list1,*p2 =list2;
while(p1!=NULL&&p2!=NULL)
{
if(p1->val<=p2->val)
{
p->next=p1;
p=p->next;
p1=p1->next;
}
else
{
p->next=p2;
p=p->next;
p2=p2->next;
}
}
while(p1!=NULL)
{
p->next=p1;
p=p->next;
p1=p1->next;
}
while(p2!=NULL)
{
p->next=p2;
p=p->next;
p2=p2->next;
}
return res;
}
int * merge(int * arr1,int la, int * arr2,int lb)
{
int i=0,j=0;
int * arr = new int[la+lb];
int t=0;
while(i<la&&j<lb)
{
if(arr1[i]<=arr2[j])
{
arr[t++]=arr1[i];
i++;
}
else
{
arr[t++]=arr2[j];
j++;
}
}
while(i<la)
{
arr[t++]=arr1[i];
i++;
}
while(j<lb)
{
arr[t++]=arr2[j];
j++;
}
return arr;
}
void setLinkData(node * & list1 , node * & list2)
{
node * node1 = new node(2);
node * node2 = new node(3);
node * node3 = new node(7);
node * node4= new node(9);
node1->next=node2;
node2->next=node3;
node3->next=node4;
list1=node1;
node * node5 = new node(1);
node * node6 = new node(4);
node * node7 = new node(6);
node * node8 = new node(8);
node5->next=node6;
node6->next=node7;
node7->next=node8;
list2=node5;
}
int main()
{
node * list1;
node * list2;
setLinkData(list1,list2);
int arr1[]={1,6,15,17,19};
int arr2[]={2,4,6,8,10};
int * arr = merge(arr1,5,arr2,5);
node * ans = merge(list1,list2);
//Print result
int length=10;
for(int i=0;i<10;i++)
{
cout<<*arr<<endl;
arr++;
}
while(ans!=NULL)
{
cout<<ans->val<<endl;
ans=ans->next;
}
return 0;
}
——————————————————————————————————————
void Merge(SeqList R,int low,int m,int high)
{//将两个有序的子文件R[low..m)和R[m+1..high]归并成一个有序的
//子文件R[low..high]
int i=low,j=m+1,p=0; //置初始值
RecType *R1; //R1是局部向量,若p定义为此类型指针速度更快
R1=(ReeType *)malloc((high-low+1)*sizeof(RecType));
if(! R1) //申请空间失败
Error("Insufficient memoryavailable!");
while(i<=m&&j<=high) //两子文件非空时取其小者输出到R1[p]上
R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++];
while(i<=m) //若第1个子文件非空,则复制剩余记录到R1中
R1[p++]=R[i++];
while(j<=high) //若第2个子文件非空,则复制剩余记录到R1中
R1[p++]=R[j++];
for(p=0,i=low;i<=high;p++,i++)
R[i]=R1[p];//归并完成后将结果复制回R[low..high]
} //Merge
——————————————————————————————————————
二路归并排序(链式存储)
以单链表为存储结构, 实现二路归并排序的算法
要求链表不另外占用存储空间, 排序过程中不移动结点中的元素, 只改各链结点中的指针, 排序后r仍指示结果链表的第一个结点
先 对待排序的单链表进行一次扫描, 将它划分为若干有序的子链表, 其表头指针存放在一个指针队列中。当队列不空时重复执行, 从队列中退出两个有序子链 表, 对它们进行二路归并, 结果链表的表头指针存放到队列中。如果队列中退出一个有序子链表后变成空队列, 则算法结束。这个有序子链表即为所求。
- 两路归并算法
- void merge ( ListNode * ha, ListNode * hb,, ListNode *& hc ) {
- ListNode *pa, *pb, *pc ;
if ( ha→data<= hb→data ) { hc = ha; pa = ha→link; pb = hb; }
else { hc = hb; pb = hb→link; pa = ha ; }
pc = hc;
while ( pa && pb )
if (pa→data <= pb→data)
{ pc→link = pa; pc = pa;
pa = pa→link;
}
else
{ pc→link = pb; pc = pb;
pb = pb→link;
}
if ( pa ) pc→link= pa;
else pc→link = pb;
}
(2) 归并排序主程序
void mergesort ( ListNode * r ) {
ListNode * s, t; Queue Q ;
if ( ! r ) return;
s = r;
Q.EnQueue( r );
while ( s ) {
t = s→link;
while ( t != 0 && s→data <= t→data ) { s = t; t = t→link; }
if ( t ) {
s→link = 0; s = t;
Q.EnQueue( s );
}
}
while ( !Q.IsEmpty( ) ) {
r = Q.DlQueue( );
if ( Q.IsEmpty( ) ) break;
s = Q.DlQueue( );
merge( r, s, t );
Q.EnQueue( t );
}
}2路归并排序法?你是指mergesort?C+++是什么语言?
template<typename T>void merge(T a[],int i,int j,int k){
int b=i,c=j+1,d=0;
T *temp=new T[k-i+1];
while(b<=j&&c<=k){
if(a[b]<a[c]) temp[d++]=a[b++];
else temp[d++]=a[c++];
}
if(b<=j){
while(b<=j) temp[d++]=a[b++];
}
if(c<=k){
while(c<=k)temp[d++]=a[c++];
}
d=0;
for(b=i;b<=k;b++)
a[b]=temp[d++];
delete[] temp;
}
template<typename T>void msort(T a[],int i,int j){
if(j-i<0) return;
else{
int mid=(i+j)/2;
msort(a,i,mid);
msort(a,mid+1,j);
merge(a,i,mid,j);
}
}
template<typename T> void merge_sort(T a[],int n){
msort(a,0,n-1);
}