//若都执行完则设定程序结束信号量
return0;
}
选择排序思想:每一次都从无序的数据中找出最小的元素,然后和中间已经有序的元素序列的后一个元素进行交换,这样整个源序列才会分成两部份,前面一部分是尚未排好序的有序序列,后面一部分是无序的,用于选出最小的元素。循环N次之后,前面的有序序列加长到和源序列一样长,后面的无序部分长度变为0,排序就完成了。
unsignedlong__stdcall SelectSort(void* theArray)
{
long* Array= ((MySafeArray*)theArray)->data;
intiLength= ((MySafeArray*)theArray)->iLength;
longlMin,lSwap;
inti,j,iMinPos;
for(i=0;i< iLength-1;i++)
{
lMin= Array[i];

iMinPos= i;
for(j=i+ 1;j<= iLength-1;j++)//从无序的元素中找出最小的元素
{
if(Array[j]< lMin)
{
iMinPos= j;
lMin= Array[j];
}
}
//把选出的元素交换拼接到有序序列的最终
lSwap= Array[i];
Array[i]= Array[iMinPos];
Array[iMinPos]= lSwap;
}
PrintResult(Array,iLength,"Select Sort");//向控制台打印排序结果
InterlockedIncrement(&ThreadCompleted);//返回前让线程完成数标记加1
if(ThreadCompleted== 4)SetEvent(evtTerminate);//检查能否其他线程都未执行完
//若都执行完则设定程序结束信号量
return0;
}
堆排序思想:堆:数据元素从1至N排列成一棵二叉树,而且这株树的每一个子树的根都是该树中的元素的最小或最大的元素这种即使一个无序数据集合是一个堆那么,根元素就是最小或最大的元素堆排序就是不断对剩下的数据建堆,把最小或最大的元素析透出来。下面的算法,就是从最后一个元素开始,依据一个节点比父节点数值大的方法对所有元素进行调整,这样调整一次就产生一个堆,第一个元素就是最小的元素。然后再对剩下的无序数据再进行建堆,注意此时上面的无序数据元素的序数都应改变,如第一次建堆后,第二个元素都会成为堆的第一个元素。
unsignedlong__stdcall HeapSort(void* theArray)
{
long* Array= ((MySafeArray*)theArray)->data;
intiLength= ((MySafeArray*)theArray)->iLength;
inti,j,p;
longswap;
for(i=0;i{
for(j= iLength- 1;j>i;j--)//从最后倒数上去非常字节点跟父节点
{
p= (j- i- 1)/2+ i;//计算父结点键值下标
//注意到树结点序数和函数下标不是等同的,因为建堆的元素个数逐个递减
if(Array[j]< Array[p])//如果父节点数值大则交换父节点和字节点
{
swap= Array[j];
Array[j]= Array[p];
Array[p]= swap;
}
}
}
PrintResult(Array,iLength,"Heap Sort");//向控制台打印排序结果
InterlockedIncrement(&ThreadCompleted);//返回前让线程完成数标记加1
if(ThreadCompleted== 4)SetEvent(evtTerminate);//检查能否其他线程都未执行完
//若都执行完则设定程序结束信号量
return0;
}
插入排序思想:把源数据序列看成两半ccriticalsection 调用 2次,前面一半是有序的,后面一半是无序的,把无序的数据从头到尾逐个逐个的插入到后面的有序数据中,使得有序的数据的个数不断增大,同时无序的数据个数就越来越少,最后所有元素就会显得有序。
unsignedlong__stdcall InsertSort(void* theArray)
{
long* Array= ((MySafeArray*)theArray)->data;
intiLength= ((MySafeArray*)theArray)->iLength;
inti=1,j=0;
longtemp;
for(i=1;i{
temp= Array[i];//取出序列里面无序数据的第一个元素值
for(j=i;j>0;j--)//和中间的有序数据逐个进行非常找出适合的插入位置
{
if(Array[j- 1]>temp)//如果该元素比插入值大则后移
Array[j]= Array[j- 1];
else//如果该元素比插入值小,那么该位置的后一位就是插入元素的位置
break;
}
Array[j]= temp;
}
PrintResult(Array,iLength,"Insert Sort");//向控制台打印排序结果
InterlockedIncrement(&ThreadCompleted);//返回前让线程完成数标记加1
if(ThreadCompleted== 4)SetEvent(evtTerminate);//检查能否其他线程都未执行完
//若都执行完则设定程序结束信号量
return0;
}
快速排序思想:快速排序是分治思想的一种应用,它先选择一个支点,然后把小于支点的元素交换到支点的前面,把高于支点的元素交换到支点的左边。然后再对支点左边部分跟后面部分进行相同的处理,这样若干次之后,数据都会显得有序。下面的推动使用了泛型建立两个游标:iLow,iHigh;iLow指向序列的第一个元素,iHigh指向最后一个先选第一个元素成为支点,并把它的值存储在一个辅助变量里。那么第一个位置就变为空并可以放置其他的元素。 这样从iHigh指向的元素开始往前移动游标,iHigh查找比支点小的元素,如果找到,则把它摆放至空置了的位置(现在是第一个位置),然后iHigh游标停止移动,这时iHigh指向的位置被空置,然后移动iLow游标寻找比支点大的元素放置到iHigh指向的空置的位置,如此往复直至iLow与iHigh相等。最后使用递归对左右两个别进行同样处理
intQuickSort(long* Array,intiLow,intiHigh)
{
if(iLow>= iHigh)return1;//递归结束条件
longpivot= Array[iLow];
intiLowSaved= iLow,iHighSaved= iHigh;//保已改变的iLow,iHigh值保存起来
while(iLow< iHigh)
{
while(Array[iHigh]>= pivot&& iHigh>iLow)//寻找比支点大的元素
iHigh-- ;
Array[iLow]= Array[iHigh];//把找到的元素放置至空置的位置
while(Array[iLow]< pivot&& iLow< iHigh)//寻找比支点小的元素
iLow++ ;
Array[iHigh]= Array[iLow];//把找到的元素放置至空置的位置
}
Array[iLow]= pivot;//把支点值放置至支点位置,这时支点位置是空置的
//对左右部分分别进行递归处理
QuickSort(Array,iLowSaved,iHigh-1);
QuickSort(Array,iLow+1,iHighSaved);
return0;
}
//每一个线程都要使用这个变量进行输出,而且只有一个显示器,产生多个线程
//竞争对控制台的使用权。
voidPrintResult(long* Array,intiLength,constchar* HeadStr)
{
WaitForSingleObject(evtPrint,INFINITE);//等待事件有信号
//EnterCriticalSection(&csPrint); //标记有线程进入临界区
//WaitForSingleObject(mtxPrint, INFINITE); //等待互斥量空置(没有线程拥有它)
inti;
printf("%s: ",HeadStr);
for(i=0;i{
printf("%d,",Array[i]);
Sleep(100);//延时(可以去掉)
只是使得多线程对临界区访问的弊端比较易于看得到
如果你把临界控制的句子注释掉,输出才会显得更凌乱,各个排序的结果会
分插间隔着输出,如果不延时就不容易看到这些不对临界区控制的结果
}
printf("%dn",Array[i]);
SetEvent(evtPrint);//把事件信号量恢复,变为有信号
}
四、 小结
对复杂的应用程序来说,线程的应用给应用程序提供了高效、快速、安全的数据处理能力。本例子讲述了线程处理中常常见到的疑问,希望对观众朋友有一定的帮助,起到抛砖引玉的作用。
感兴趣的快来看:返回搜狐,查看更多
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-143108-2.html
拉森号可不能说是老旧军舰