准备工作
#define swap(a,b) {typeof(a) t=a;a=b;b=t;}
冒泡排序
能监测到数据是否有序,一旦监测到有序则停止排序
void bubble_sort(int* arr,size_t len)
{
for(int i = len-1; i > 0; i--) // i为最后一个
{
bool flag = true; // 假定已经排好
for(int j = 0; j < i; j++)
{
if(arr[j] > arr[j+1])
{
swap(arr[j],arr[j+1]);
flag = false; // 发生交换,将标志设为假,表示没有拍好
}
}
if(flag) break; // 一旦发现没有数的交换,说明数已排好,跳出
}
}
插入排序
void insert_sort(int* arr,size_t len)
{
for(int i = 1; i < len; i++)
{
int temp = arr[i], k = i; // k用于记录新的位置
for(int j = i-1; j >= 0 && arr[j] > temp; j--)
{
arr[j+1] = arr[j];
k = j;
}
arr[k] = temp;
}
}
选择排序
void select_sort(int* arr,size_t len)
{
for(int i = len-1; i > 0; i--)
{
int max = i; // 假定i就是最大的
for(int j = 0; j < i; j++)
{
if(arr[j] > arr[max])
{
max = j;
}
}
if(max != i) // i改变了证明原来的i不是最大的
{
swap(arr[max],arr[i]);
}
}
}
比较完后再交换值,大大提升了运行速度
快速排序
void _quick_sort(int* arr,size_t left,size_t right)
{
if(left >= right)
{
return;
}
int pi = (left+right)/2; // 计算标杆的下标
int pv = arr[pi]; // 备份标杆的值
int l = left, r = right; // 备份左右下标
while(l < r) // 左右下标相遇时结束
{
while(l < pi && arr[l] <= pv) // 在标杆的左边寻找比它大的数据
{
l++;
}
if(l < pi) // 若以l<pi结束的,证明arr[l] > pv,找到了比pv大的值
// 如果没有超出范围,说明找到比标杆大的值
{
arr[pi] = arr[l]; // 与标杆交换位置
pi = l; // 记录新的标杆下标
}
while(pi < r && arr[r] >= pv) // 在标杆的右边寻找比它小的数据
{
r--;
}
if(pi < r) // 如果没有超出范围,说明arr[r]<pv,找到比标杆小的值
{
arr[pi] = arr[r];
pi = r;
}
}
arr[pi] = pv; // 还原标杆的值
if(pi - left > 1)
{
_quick_sort(arr,left,pi-1);
}
if(right - pi > 1)
{
_quick_sort(arr,pi+1,right);
}
}
void quick_sort(int* arr,size_t len)
{
_quick_sort(arr,0,len-1);
}
堆排序
void creat_heap(int* arr,size_t root,size_t len)
{
if(root >= len)
{
return;
}
int left = root*2+1; // 计算左子结点的下标
int right = root*2+2; // 计算右子结点的下标
creat_heap(arr,left,len);
creat_heap(arr,right,len);
int max = root;
if(left < len) // 才有子结点
{
if(arr[left] > arr[max])
{
max = left;
}
}
if(right < len) // 才有子结点
{
if(arr[right] > arr[max])
{
max = right;
}
}
if(max != root)
{
swap(arr[max],arr[root]);
}
}
void heap_sort(int* arr,size_t len)
{
for(int i = 0; i < len; i++)
{
creat_heap(arr,0,len-i);
swap(arr[0],arr[len-i-1]);
}
}
归并排序
void merge(int* arr,size_t left,size_t pi,size_t right)
{
int i = left, j = pi+1, k = 0;
int temp[right - left + 1]; // 临时空间,内部合并
while(i <= pi && j <= right) // 两个都到边界
{
if(arr[i] < arr[j])
{
temp[k++] = arr[i++];
}
else
{
temp[k++] = arr[j++];
}
}
while(i <= pi) // 只有一个到边界
{
temp[k++] = arr[i++];
}
while(j <= right)
{
temp[k++] = arr[j++];
}
for(int i = 0; i <= (right-left); i++)
{
arr[i+left] = temp[i]; // 从left开始后的i个复制回原空间
}
}
void _merge_sort(int* arr,size_t left,size_t right)
{
if(left >= right)
{
return;
}
int pi = (left+right)/2;
_merge_sort(arr,left,pi); // 分左段
_merge_sort(arr,pi+1,right); // 分右段
merge(arr,left,pi,right); // 合并
}
void merge_sort(int* arr,size_t len)
{
_merge_sort(arr,0,len-1);
}