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

    }

     

     

  • 相关阅读:
    Android之退出整个应用方法
    自定义popupwindow(解决位置控制困惑)
    日期格式转换
    简单用于测试的listview的视图
    复制res下文件进sd卡
    自定义九宫格式的弹出menu
    动画隐藏或者显示控件
    截取p3片段
    微信几种动画进入退出应用
    codeforce Round On Sum of Fractions + stl 的应用
  • 原文地址:https://www.cnblogs.com/lsx1993/p/4841506.html
Copyright © 2011-2022 走看看