69,373
社区成员
发帖
与我相关
我的任务
分享
const int N = 200000;
int O = 0;
int* GenRandom()
{
srand( (unsigned)time( NULL ) );
int* a = new int[N];
for (int i = 0; i < N; i++)
{
a[i] = rand()*rand() ;
}
return a;
}
SYSTEMTIME StartTime = {0};
FILETIME StartFileTime = {0};
SYSTEMTIME EndTime= {0};
FILETIME SEndFileTime= {0};
int _tmain(int argc, _TCHAR* argv[])
{
int* a = GenRandom();
GetLocalTime(&StartTime);
printf("timeBefore %d:%d:%d \r\n", StartTime.wMinute, StartTime.wSecond, StartTime.wMilliseconds);
BubbleSort(a);
/*SelectionSort(a);
InsertSort(a);
MergeSort(a,0,N-1);
QuickSort(a,0,N-1);
HeapSort(a,0,N);*/
GetLocalTime(&EndTime);
printf("timeAfter %d:%d:%d \r\n", EndTime.wMinute, EndTime.wSecond, EndTime.wMilliseconds);
return 0;
}
#include "stdafx.h"
#include "windows.h"
#include "time.h"
const int N = 100000;
int O = 0;
int* GenRandom()
{
srand( (unsigned)time( NULL ) );
int* a = new int[N];
for (int i = 0; i < N; i++)
{
a[i] = rand()*rand();
}
return a;
}
void swap(int& a, int& b)
{
int temp = 0;
temp = a;
a = b;
b = temp;
}
//small -> large
void SelectionSort(int* ua)
{
//round times,遍历N次
for (int i = 0; i < N-1; i++)
{
int nMinIndex = i; //最小值的索引
//每次确定一个值,从第一个值开始。。。第二次从第二个值开始
for (int j = i + 1; j < N; j++)
{
if( ua[nMinIndex] >= ua[j] )
{
nMinIndex = j;
}
O++;
}
swap(ua[i], ua[nMinIndex] );
}
}
//small -> large
void InsertSort(int* ua)
{
//round times
for (int i = 1; i <= N; i++)
{
for (int j = i; j > 0; j--)
{
if( ua[j] < ua[j-1] )
{
swap(ua[j], ua[j-1] );
}
}
}
}
//small -> large
void BubbleSort(int* ua)
{
O = 0;
//round times
for (int i = 0; i < N; i++)
{
/*printf("round %d \r\n", i);
for (int i = 0; i < N; i++)
{
printf("a[%d]=%d \r\n",i, *(ua+i));
} */
for (int j = 0; j < (N-i-1); j++)
{
if(ua[j] > ua[j+1])
{
swap(ua[j], ua[j+1] );
}
O++;
}
}
}
void Merge(int* ua, int nStart, int nMid, int nEnd)
{
int a[N];
int i = nStart;
int j = nMid + 1;
for (int k = nStart; k <= nEnd; k++)
{
a[k] = ua[k];
}
for (int k = nStart; k <= nEnd; k++)
{
if(i > nMid)
{
ua[k] = a[j++];
}
else if(j > nEnd)
{
ua[k] = a[i++];
}
else if( a[j] < a[i])
{
ua[k] = a[j++];
}
else
{
ua[k] = a[i++];
}
/*printf("round %d \r\n", k);
for (int k = nStart; k < nEnd; k++)
{
printf("a[%d]=%d \r\n", k, *(ua + k));
} */
}
}
//small -> large
void MergeSort(int* ua, int nStart, int nEnd)
{
//递归退出条件
if(nStart >= nEnd)
{
return;
}
int nMid = nStart + (nEnd - nStart) / 2;
MergeSort(ua, nStart, nMid);
MergeSort(ua, nMid+1, nEnd);
Merge(ua, nStart, nMid, nEnd);
}
int QuickPartition(int* ua, int nStart, int nEnd)
{
int i = nStart;
int j = nEnd + 1;
//中点值
int nFlagValue = ua[nStart];
while(1)
{
//找到左边大于中点的值,记录索引
while( ua[++i] < nFlagValue )
{
if( i == nEnd)
{
break;
}
}
//找到右边小于中点的值,记录索引
while( ua[--j] > nFlagValue )
{
if( j == nStart)
{
break;
}
}
//两边向中间靠拢的过程中相遇则退出
if( i >= j)
{
break;
}
//交换两边的值
swap( ua[i], ua[j] );
}
//将右边最后一个小于中点值的数与中点值交换位置,
//保证中点值的左边都小于中点值,右边都大于中点值
swap( ua[nStart], ua[j] );
//返回将右边最后一个小于中点值的数的索引,做为右边部分的中点值。
return j;
}
void QuickSort(int* ua, int nStart, int nEnd)
{
//递归退出条件
if(nStart >= nEnd)
{
return;
}
int nMid = QuickPartition(ua, nStart, nEnd);
QuickSort(ua, nStart, nMid-1);
QuickSort(ua, nMid+1, nEnd);
}
void HeapAdjust(int* ua, int nStart, int nEnd)
{
int nMaxIndex = 0;
while ( ( 2*nStart + 1) < nEnd )
{
nMaxIndex = 2*nStart + 1;
if ( ( 2*nStart + 2) < nEnd)
{
//比较左子树和右子树,记录较大值的Index
if (ua[2*nStart + 1] < ua[2*nStart + 2])
{
nMaxIndex++;
}
}
//如果父结点大于子节点,则退出,否则交换
if (ua[nStart] > ua[nMaxIndex])
{
break;
}
else
{
swap( ua[nStart], ua[nMaxIndex] );
//堆被破坏,继续递归调整
nStart = nMaxIndex;
}
}
/*for (int i = 0; i < N; i++)
{
printf("%d ",ua[i]);
}
printf("\r\n");*/
//printf("%d ", O++);
}
void HeapSort(int* ua, int nStart, int nEnd)
{
for (int i = nEnd/2 -1; i >= 0 ; i--)
{
HeapAdjust( ua, i, nEnd);
}
for (int i = nEnd-1; i > 0; i--)
{
swap(ua[0], ua[i]);
HeapAdjust(ua, 0, i);
}
}
SYSTEMTIME StartTime = {0};
FILETIME StartFileTime = {0};
SYSTEMTIME EndTime= {0};
FILETIME SEndFileTime= {0};
int _tmain(int argc, _TCHAR* argv[])
{
int* a = GenRandom();
GetLocalTime(&StartTime);
printf("timeBefore %d:%d:%d \r\n", StartTime.wMinute, StartTime.wSecond, StartTime.wMilliseconds);
//BubbleSort(a);
//SelectionSort(a);
//InsertSort(a);
//MergeSort(a,0,N-1);
//QuickSort(a,0,N-1);
HeapSort(a,0,N);
GetLocalTime(&EndTime);
printf("timeAfter %d:%d:%d \r\n", EndTime.wMinute, EndTime.wSecond, EndTime.wMilliseconds);
printf("times %d \r\n", O);
return 0;
}
template <typename T>
inline void QuickSort(T arr[], int n) //快速排序
{
QSpartition(arr, 0, n - 1);
InsertSort(arr, n); //最后用插入排序对整个数组排序
}
template <typename T>
void QSpartition(T arr[], int low, int high) //快速排序递归函数
{
// if (low >= high) //有插入排序,不需要这句
// continue;
const int min_insert = 128;
if (high - low < min_insert) //数据小于一定数量的时候用直接插入排序
{
return; //最后用插入排序对整个数组排序
}
int i, j;
T temp;
//下面一段是前中后3个数据进行插入排序
i = (low + high) / 2;
if (arr[i] < arr[low])
{
temp = arr[i];
arr[i] = arr[low];
arr[low] = temp;
}
if (arr[high] < arr[i])
{
temp = arr[high];
arr[high] = arr[i];
arr[i] = temp;
if (arr[i] < arr[low])
{
temp = arr[i];
arr[i] = arr[low];
arr[low] = temp;
}
}
// if (high - low < 3) //小区间用插入排序,这里就不需要判断了
// return; //不用插入排序,只有2个数据的时候排序错误
temp = arr[i];
arr[i] = arr[low + 1]; //中值放在最左边
i = low + 1; //左右边界缩小1
j = high - 1; //边界2个数字插入排序排过,满足左<=中<=右
while (i < j)
{
while (temp < arr[j] && i < j) //从右往左扫描小于目标的值,应该放在左半部分
j--;
if (i < j) //找到后放在左边
arr[i++] = arr[j];
else
break;
while (temp > arr[i] && i < j) //从左往右扫描大于目标的值,要放在右边
i++;
if (i< j)
arr[j--] = arr[i];
else
break;
}
arr[i] = temp; // i = j,正好是分界线,回填目标值
if ((i - low) > 1)
QSpartition(arr, low, i - 1); //递归左边
if ((high - i) > 1)
QSpartition(arr, i + 1, high); //递归右边
}
template <typename T>
void InsertSort(T arr[], int n) //直接插入排序
{
int i, j;
T temp;
for (i = 1; i < n; i++)
{
temp = arr[i];
for (j = i - 1; j >= 0; j--)
{
if (temp < arr[j]) //逐个往前比较,碰到大于目标的,拉过来
arr[j + 1] = arr[j];
else
break;
}
arr[j + 1] = temp; //把目标值填入空位
}
}