zoukankan      html  css  js  c++  java
  • 两路归并排序

    链表两路归并

    #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);

    }

     

     

  • 相关阅读:
    sqlplus时报Linux-x86_64 Error: 13: Permission denied
    thrift之TTransport层的缓存传输类TBufferedTransport和缓冲基类TBufferBase
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 队列操作
    Java实现 蓝桥杯 算法提高 文本加密
    Java实现 蓝桥杯 算法提高 合并石子
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4841506.html
Copyright © 2011-2022 走看看