#define SIZE_OF_ARRAY(x) (sizeof(x) / sizeof(x[0]))
void swap(int &a,int &b)
{
int tmp = a;
a = b;
b = tmp;
}
#define OUT_PUT_DEBUG_ARRAY(x,len) do \
{\
for (int i = 0; i < len; i++)\
{\
printf("%6d",x[i]);\
}\
printf("\r\n--------------------------\r\n");\
} while (0);
// 0.冒泡排序
// 从头开始,依次遍历所有元素,当遇到比当前元素小的,直接交换
void BubbleSort_Right(int *arr, int len)
{
for (int i = 0; i < len - 1; ++i)
{
for (int j = 0; j < len - 1 - i; ++j)
{
if (arr[j + 1] > arr[j])
{
swap(arr[j + 1], arr[j]);
}
}
}
}
// 1.选择排序
// 从头开始,依次遍历所有元素,找出当前坐标到结尾最小的元素,进行交换
// 思想与冒泡排序差不多,只不过交换放到了循环外,减少了交换次数
void SelectSort(int *arr, int len)
{
for (int i = 0;i < len - 1;++i)
{
int k = i;
for (int j = i + 1;j < len;++j)
{
//if (arr[i] > arr[j]) -- 此处错误,多谢指正@_@ @tuohaohu
if (arr[k] > arr[j])
{
k = j;
}
}
if (i != k)
{
swap(arr[i], arr[k]);
}
}
}
// 2.插入排序
// 总所周知,当只有一个元素时,待排数据为有序数据
// 假定数组arr[n],当 0 < k < n时,a[0]~a[k-1]有序,a[k]~a[n-1]无序
// 此时,将arr[k]拿出来,将arr[0]~arr[k-1]从k-1开始往左遍历,如果a[j] > a[k],则将a[j]左移,指导a[j] < a[k],此时将a[k]放到a[j+1],arr[0]~arr[k]变为有序序列
// 当遍历晚arr[n]时,此时数据将为有序序列
void InsertSort(int *arr, int len)
{
if (len <= 1)
{
return;
}
for (int i = 1; i < len;++i)
{
int tmp = arr[i];
for (int j = i - 1;j >= 0;--j)
{
if (arr[j] >= tmp)
{
arr[j + 1] = arr[j];
}
else
{
arr[j + 1] = tmp;
break;
}
}
}
}
// 3.二分插入排序
// 因为直接插入排序在搜索插入位置的时候,效率很低,对于大数组,尤其不适用
// 于是采用二分插入排序,又叫折半插入排序, 二分插入排序是采用折半查找法寻找要插入的位置
// 二分搜索:
void BinaryInsertSort(int *arr, int len)
{
for (int i = 1; i < len; ++i)
{
int tmp = arr[i];
int iHigh = i - 1;
int iLow = 0;
int iMid = 0;
while (iLow arr[iMid] )
{
iLow = iMid + 1;
}
else
{
iHigh = iMid - 1;
}
}
// 将 iMid 到 i 的数据左移
for (int j = i; j > iMid; --j)
{
arr[j] = arr[j - 1];
}
arr[iLow] = tmp;
}
}
// 4.归并排序
// 将待排序数据,从中间分为2段A和B,使A和B分别有序后,再将A和B使用插入排序
// 退出条件为
void MergeSort(int *arr, int beg,int end)
{
//OUT_PUT_DEBUG_ARRAY(&arr[beg], end - beg);
if (beg >= end)
{
return;
}
if (beg == end - 1)
{
if (arr[beg] > arr[beg + 1])
{
swap(arr[beg], arr[beg + 1]);
}
return;
}
// 将beg到end分为2段A和B,并将A和B分别使用归并排序
int iL1 = beg;
int iH1 = (beg + end) / 2;
int iL2 = iH1 + 1;
int iH2 = end;
MergeSort(arr, iL1, iH1);
MergeSort(arr, iL2, iH2);
// 将A 和 B 排序完毕后,合并A和B——使用插入排序
for (int i = iL2; i = iL1; --j)
{
arr[j + 1] = arr[j];
if (tmp > arr[j])
{
arr[j + 1] = tmp;
break;
}
}
}
}
// 5.快速排序
// 1.以左右两端i和j为起点,从右往左开始,找到比最左端小的数,停止坐标记为A,从左往右找到比最左端大的数,停止坐标记为A。交换A和B标记的数。
// 2.重复第一点,直到A == B,将此事的坐标所标识的值与最开始的数据交换。记此时的坐标为K
// 3.分别对 i~K-1 与 K+1 ~ j 重复上诉1、2两点
void quickSort(int *arr, int left, int right)
{
if (left > right)
{
return;
}
int tmp = arr[left];
int iLeft = left;
int iRight = right;
while (left != right)
{
while (right > left && (arr[right] >= tmp))
{
right--;
}
while (right > left && (arr[left] <= tmp))
{
left++;
}
if (left < right)
{
swap(arr[left], arr[right]);
}
}
arr[iLeft] = arr[left];
arr[left] = tmp;
quickSort(arr, iLeft, left - 1);
quickSort(arr, left + 1, iRight);
}