码迷,mamicode.com
首页 > 编程语言 > 详细

两路归并排序

时间:2015-09-26 23:59:17      阅读:439      评论:0      收藏:0      [点我收藏+]

标签:

链表两路归并

#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仍指示结果链表的第一个结点

 

先 对待排序的单链表进行一次扫描, 将它划分为若干有序的子链表, 其表头指针存放在一个指针队列中。当队列不空时重复执行, 从队列中退出两个有序子链 表, 对它们进行二路归并, 结果链表的表头指针存放到队列中。如果队列中退出一个有序子链表后变成空队列, 则算法结束。这个有序子链表即为所求。

 

  1. 两路归并算法
  2. void merge ( ListNode * ha, ListNode * hb,, ListNode *& hc ) {
  3. 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);

}

 

 

两路归并排序

标签:

原文地址:http://www.cnblogs.com/lsx1993/p/4841506.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!