归并排序详解

一.概念:

归并是指将若干个已排序的子文件合并成一个有序的文件。

二.基本思路:

         设两个有序的子文件(相当于输入堆)放在同一向量中相邻的位置上:R[low..m],R[m+1..high],先将它们合并到一个局部的暂存向量R1(相当于输出堆)中,待合并完成后将R1复制回R[low..high]中。
      合并过程中,设置i,j和p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较R[i]和R[j]的关键字,取关键字较小的记录复制到R1[p]中,然后将被复制记录的指针i或j加1,以及指向复制位置的指针p加1。
      重复这一过程直至两个输入的子文件有一个已全部复制完毕(不妨称其为空),此时将另一非空的子文件中剩余记录依次复制到R1中即可。

三.图形解析

首先我们来讨论归并算法,归并算法将一系列数据放到一个向量中,索引范围为[first,last],这个序列由两个排好序的子表构成,以索引终点(mid)为分界线,以下面一个序列为例

    7,10,19,25,12,17,21,30,48

   这样的一个序列中,分为两个子序列 7,10,19,25  和 12,17,21,30,48,如下图所示:

image

再使用归并算法的时候的步骤如下:

 第一步:比较v[indexA]=7和v[indexB]=12,将较小的v[indexA]取出来放到临时向量tempArray中,然后indexA加1

image

 第二步:比较v[indexA]=10和v[indexB]=12,将较小的10放到临时变量tempArray中,然后indexA++;

 image

第三步:比较v[indexA]=19与v[indexB]=12,将较小的12存放到临时变量tempArray中,然后indexB++;

  image

第四步到第七步:按照以上规则,进行比对和存储,得到如下结果:

  image

最后一步:将子表b中剩余项添加到临时向量tempArray中

  image


四.单线程程序c语言代码:

#include<stdio.h>
#include<stdlib.h>
void merge(int a[],int start,int end)
{
int mid;
int l1,l2;
int *left,*right;
int i,j,k;
mid=(start+end)/2;
l1=mid-start+1;
l2=end-mid;
left=(int *)malloc(sizeof(int)*l1);
right=(int *)malloc(sizeof(int)*l2);
for(i=0;i<l1;i++)
left[i]=a[start+i];
for(j=0;j<l2;j++)
right[j]=a[mid+1+j];
i=0;j=0;k=start;
while(i<l1&&j<l2)
{
if(left[i]<right[j])
{
a[k]=left[i];
    i++;
}
else
{


a[k]=right[j];
j++;
}
k++;
}
while(i<l1)
a[k++]=left[i++];
while(j<l2)
a[k++]=right[j++];
free(left);
free(right);
}
void sort(int a[],int start, int end)
{
int mid ;
if(start>=end)//递归排序结束条件
return;
mid=(start+end)/2;
sort(a,start,mid);//排左子序列
sort(a,mid+1,end);//排右子序列
merge(a,start,end);//有序归并


}
main()
{
int a[]={3,2,6,5,4,19,1,30,45,21};
int i;
sort(a,0,(sizeof(a)/sizeof(a[0])-1));//sizeof(a)/sizeof(a[0])表示数组中元素的总个数


for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
printf("%4d",a[i]);
printf("\n");


}


执行结果:

多线程c程序代码:

#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define MAX 10
pthread_t thread[2];//数据类型:pthread_t:线程句柄
pthread_mutex_t mut;//试图占有互斥锁(不阻塞操作)。即,当互斥锁空闲时,将占有该锁;否则,立即返回。
int number=0, i;
void *thread1()
{
        printf ("thread1 : I'm thread 1\n");
        for (i = 0; i < MAX; i++)
        {
                printf("thread1 : number = %d\n",number);
                pthread_mutex_lock(&mut);//占有互斥锁(阻塞操作)
                        number++;
                pthread_mutex_unlock(&mut);// 释放互斥锁
                sleep(2);
        }
        printf("thread1 :主函数在等我完成任务吗?\n");
        pthread_exit(NULL);//终止当前线程
}
void *thread2()
{
        printf("thread2 : I'm thread 2\n");
        for (i = 0; i < MAX; i++)
        {
                printf("thread2 : number = %d\n",number);
                pthread_mutex_lock(&mut);
                        number++;
                pthread_mutex_unlock(&mut);
                sleep(3);//调用进行中唤醒程序?
        }
        printf("thread2 :主函数在等我完成任务吗?\n");
        pthread_exit(NULL);
}
void thread_create(void)//pthread_create():创建一个线程
{
        int temp;
        memset(&thread, 0, sizeof(thread));          //comment1???
        /*创建线程*/
        if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)       //comment2
                printf("线程1创建失败!\n");
        else
                printf("线程1被创建\n");
        if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)  //comment3
                printf("线程2创建失败");
        else
                printf("线程2被创建\n");
}
void thread_wait(void)
{
        /*等待线程结束*/
        if(thread[0] !=0) {                   //comment4
                pthread_join(thread[0],NULL);
                printf("线程1已经结束\n");
        }
        if(thread[1] !=0) {                //comment5
                pthread_join(thread[1],NULL);
                printf("线程2已经结束\n");
        }
}
int main()
{
        /*用默认属性初始化互斥锁*/
        pthread_mutex_init(&mut,NULL);
        printf("我是主函数哦,我正在创建线程,呵呵\n");
        thread_create();
        printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
        thread_wait();
        return 0;
}


//注释参考网站:http://zh.wikipedia.org/wiki/POSIX线程

执行结果:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值