多线程堆排序算法C语言实现

多线程堆排序算法C语言实现

代码主要实现对八十万个长整型数据的排序;利用8个线程实现,每个线程负责十万个数,数据由rand()函数产生。
代码如下:

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<time.h>
#include<sys/time.h>
#include<limits.h>
#include<pthread.h>

#define NTHR 8
#define NUMNUM 80
#define TNUM (NUMNUM/NTHR)

long nums[NUMNUM];
long snums[NUMNUM];

pthread_barrier_t b;

struct heap{
    long array[TNUM+1];
    long heapSize;
};
typedef struct heap Heap;
typedef long index;
int siftdown(Heap *heap,index i){
    index parent,largchild;
    long siftkey;
    bool spotfound;
    siftkey=heap->array[i];
    parent=i;
    spotfound=false;
    while(2*parent<=heap->heapSize && !spotfound){
        if(2*parent<heap->heapSize && 
                heap->array[2*parent]<heap->array[2*parent+1]){
                largchild=2*parent+1;   
            }else{
                largchild=2*parent;
            }
        if(siftkey<heap->array[largchild]){
            heap->array[parent]=heap->array[largchild];
            parent=largchild;
        }else
            spotfound=true;
    }
    heap->array[parent]=siftkey;
    return 0;
}

int root(Heap *heap){
    long keyout;
    keyout=heap->array[1];
    heap->array[1]=heap->array[heap->heapSize];
    heap->heapSize=heap->heapSize-1;
    siftdown(heap,1);
    return keyout;
}
int removekeys(long n,Heap *heap,long *array){
    index i;
    for(i=n;i>=1;i--){
        heap->array[i]=root(heap);
    }
}
int makeHeap(long n,Heap *heap){
    index i;
    heap->heapSize=n;
    for(i=n/2;i>=1;i--)
        siftdown(heap,i);
}

int checkResult(Heap *heap){
    for(long i=1;i<TNUM+1;i++){
        if(heap->array[i]-heap->array[i-1]<0){
            printf("fail to sort\n");
            exit(1);
        }
    }
    printf("sort succeed!\n");
    return 0;
}

int printResult(Heap *heap){
    for(long i=1;i<TNUM+1;i++){
        if(i%10==0)
            printf("\n");
        printf("%ld ",heap->array[i]);
    }   
    printf("\n");
    return 0;
}

int heapSort(long *array,long heapSize){
    int err=0;
    Heap heap;
    heap.array[0]=0;
    for(long i=1;i<heapSize+1;i++)
        heap.array[i]=array[i-1];
    makeHeap(heapSize,&heap);
    removekeys(heapSize,&heap,heap.array);
    //printResult(heap);
    err=checkResult(&heap);
    if(err!=0)
        exit(1);
    //printf("succeed!\n");
    for(long i=1;i<heapSize+1;i++){
        array[i-1]=heap.array[i];
    }
    return err;
}

void * thr_fn(void *arg){
    long idx=(long)arg;
    int err=0;
    err=heapSort(&nums[idx],TNUM);
    if(err!=0){
        printf("fail to sort");
        exit(1);
    }
    printf("sort finish!\n");
    pthread_barrier_wait(&b);
    return ((void *)0);
}

int merge(){
    long idx[NTHR];
    long i,minidx,sidx,num;

    for(i=0;i<NTHR;i++){
        idx[i]=i*TNUM;
    }
    for(sidx=0;sidx<NUMNUM;sidx++){
        num=INT_MAX;
        for(i=0;i<NTHR;i++){
            if(idx[i]<(i+1)*TNUM && (nums[idx[i]]<num)){
                num=nums[idx[i]];
                minidx=i;
            }
        }
        snums[sidx]=nums[idx[minidx]];
        idx[minidx]++;
    }
}

int main(){
    unsigned long i;
    struct timeval start,end;
    long long startusec, endusec;
    double elapsed;
    int err;
    pthread_t tid;

    srandom(1);
    for(i=0;i<NUMNUM;i++){
        nums[i]=rand()%100+1;
    }

    gettimeofday(&start,NULL);
    pthread_barrier_init(&b,NULL,NTHR+1);
    for(i=0;i<NTHR;i++){
        err=pthread_create(&tid,NULL,thr_fn,(void *)(i*TNUM));
        if(err!=0)
            printf("can't create thread\n");
    }
    pthread_barrier_wait(&b);
    merge();
    gettimeofday(&end,NULL);
    startusec=start.tv_sec*1000000+start.tv_usec;
    endusec=end.tv_sec*1000000+end.tv_usec;
    elapsed=(double)(endusec-startusec)/1000000.0;
    printf("sort took %.4f seconds\n",elapsed);
    for(i=0;i<NUMNUM;i++)
        printf("%ld\n",snums[i]);
    exit(0);
}

在主要介绍pthread_barrier_ 函数:

  • 使用屏障需要初始化,pthread_barrier_init 函数在初始化时一般把等待线程数量设置为NTHER+1(申请的线程数量加一),其实是把主线程包含在内了。
    这样做的原因是:如果只同步申请的子线程,那么子线程完成只时不知道主线程是否完成;因此在线程处理函数中每个子线程完成运算之后用pthread_barrier_wait 函数等待,主线程中也等待,这样可以保证,所有的线程都执行到屏障处之后,一起进行下一步运行。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Linux下C语言实现多线程排序的代码: ``` #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define NUM_THREADS 4 #define ARRAY_SIZE 10000 int array[ARRAY_SIZE]; void* sort(void* arg) { int id = *(int*)arg; int start = id * (ARRAY_SIZE / NUM_THREADS); int end = (id + 1) * (ARRAY_SIZE / NUM_THREADS); // 使用快速排序对数组进行排序 qsort(&array[start], end - start, sizeof(int), compare); pthread_exit(NULL); } int compare(const void* a, const void* b) { return (*(int*)a - *(int*)b); } int main() { pthread_t threads[NUM_THREADS]; int thread_ids[NUM_THREADS]; // 初始化数组 for (int i = 0; i < ARRAY_SIZE; i++) { array[i] = rand(); } // 创建线程 for (int i = 0; i < NUM_THREADS; i++) { thread_ids[i] = i; pthread_create(&threads[i], NULL, sort, &thread_ids[i]); } // 等待线程结束 for (int i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } // 合并排序结果 int sorted_array[ARRAY_SIZE]; int indexes[NUM_THREADS]; for (int i = 0; i < NUM_THREADS; i++) { indexes[i] = i * (ARRAY_SIZE / NUM_THREADS); } for (int i = 0; i < ARRAY_SIZE; i++) { int min_index = -1; for (int j = 0; j < NUM_THREADS; j++) { if (indexes[j] < (j + 1) * (ARRAY_SIZE / NUM_THREADS)) { if (min_index == -1 || array[indexes[j]] < array[indexes[min_index]]) { min_index = j; } } } sorted_array[i] = array[indexes[min_index]]; indexes[min_index]++; } // 打印排序结果 for (int i = 0; i < ARRAY_SIZE; i++) { printf("%d ", sorted_array[i]); } printf("\n"); return 0; } ``` 这个代码使用了4个线程对一个10000个整数的数组进行排序,实现了快速排序算法。每个线程排序数组的一个子集,然后合并排序结果。使用pthread库实现多线程功能,包括创建线程、等待线程结束等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值