多线程快速排序(思考)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
在CSDN看到的一位牛人实现的多线程快排,暂时没细看,但是感觉有点小问题,他的多线程快排并没有实现我所想要的那种并行计算的结果,我理想中的多线程排序<br>(这里特指快排)应该是类似于mapreduce的分拆和合并,在快排中,分拆是必然(和归并一样,基因决定嘛),分拆后的数组可以形成队列,按照核心数分给每个线程<br>进行排序,然后进行归并。打算找个时间自己实现一下。<br>#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>
 
#define NUM 10000*1000  //设置数组中的数据量,设定为1000万
 
HANDLE hMutex;
int count=0;    //记录创建线程的总数量
 
struct ThreadSortData   //定义为多线程函数传递的参数
{
    int *p; //指向数组的指针
    int i;  //数组段的起始序号
    int j;  //数组段的结束序号
};
 
DWORD WINAPI ThreadQuickSort(LPVOID lpParam)    //多线程快速排序
{
    int i=((ThreadSortData *)lpParam)->i;    //直接使用参数太麻烦,重新申请短变量并赋值
    int j=((ThreadSortData *)lpParam)->j;
    int *num=((ThreadSortData *)lpParam)->p;
    count++;
     
    int start=i;    //记录起始序号
    int end=j;  //记录结束序号
    int key=num[i]; //保存关键值
     
    while(i<j)   //排序
    {
        while(i<j && num[j]>=key)
        {
            j--;
        }
        num[i]=num[j];
         
        while(i<j && num[i]<=key)
        {
            i++;
        }
        num[j]=num[i];
    }
    num[i]=key;
     
    HANDLE hThread1;
    HANDLE hThread2;
    if((i-start)>1)  //如果本段数组关键字的左端至少有两个数据,那么继续排序
    {
        ThreadSortData *pData1=new ThreadSortData;
        pData1->i=start;
        pData1->j=i-1;
        pData1->p=num;
        hThread1=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData1,0,NULL);
    }
     
    if((end-j)>1)    //如果本段数组关键字的右端至少有两个数据,那么继续排序
    {
        ThreadSortData *pData2=new ThreadSortData;
        pData2->i=i+1;
        pData2->j=end;
        pData2->p=num;
        hThread2=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData2,0,NULL);
    }
     
    WaitForSingleObject(hThread1,INFINITE); //子线程执行完毕后主线程再继续运行
    WaitForSingleObject(hThread2,INFINITE); //子线程执行完毕后主线程再继续运行
    CloseHandle(hThread1);
    CloseHandle(hThread2);
 
    delete[] lpParam;   //释放动态内存
     
    return TRUE;
}
 
void main()
{
    srand(GetTickCount());
     
    int *num=new int[NUM];
    int temp;
    for(int i=0;i<NUM;i++)
    {
        temp=rand()+rand();
        num[i]=(temp<<16)+rand()+rand();  //为了保证数组中所有的值在-2^31到2^31-1之间均匀分布
    }
    printf("\n");
     
    ThreadSortData *pData=new ThreadSortData;   //申请的动态内存在创建的线程中释放
    pData->p=num;
    pData->i=0;
    pData->j=NUM-1;
     
    HANDLE hThread;
    hMutex=CreateMutex(NULL,FALSE,NULL);
    int time=GetTickCount();    //线程开始时计数
    hThread=CreateThread(NULL,0,ThreadQuickSort,(LPVOID)pData,0,NULL);
    WaitForSingleObject(hThread,INFINITE);  //子线程执行完毕后主线程再继续运行
    time=GetTickCount()-time;   //线程结束时所花费的时间
    CloseHandle(hThread);   //关闭线程句柄
     
/*  for(i=0;i<NUM;i++)   //输出数据
    {
        printf("%d ",num[i]);
    }
    printf("\n");*/
     
    printf("一共创建了%d个线程\n",count);   //输出总线程数
    printf("一共花费了%d毫秒\n",time); //输出总线程数
 
    delete[] num;
}

 

posted @   迈克儿  阅读(2048)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示