八大排序
1. 冒泡排序
void BulleSort(int a[], int len) // 冒泡排序
{
int i, j, temp;
for(i = 0; i < len; i++)
{
for(j = len - 1; j > i; --j) // 每次循环一次都找到最小大的值,循环次数减1
{
if(a[j] < a[j - 1])
{
temp = a[j];
a[j] = a[j - 1];
a[j - 1] = temp;
}
}
}
}
2.快速排序
// 快速排序
void QuickSort(int a[], int L, int H) // 第一次调用 QuickSort(a, 0, length - 1)
{
int i, j;
int index;
if(L >= H) // 结束条件
{
return;
}
i = L;
j = H;
index = a[i];
// 挖坑填充法
while(i < j) // 分成两部分
{
while(i < j && index <= a[j]) // 后半部分
{
j--;
}
if(i < j)
{
a[i++] = a[j];
}
while(i < j && index > a[i]) // 前半部分
{
i++;
}
if(i < j)
{
a[j--] = a[i];
}
}
// 方法2
int t;
while(i < j) // 分成两部分
{
while(i < j && index <= a[j]) // 后半部分
{
j--;
}
while(i < j && index > a[i]) // 前半部分
{
i++;
}
if(i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
a[left]=a[i];
/****************/
a[i] = index;
QuickSort(a, L, i - 1);
QuickSort(a, i + 1, H);
}
3. 直接插入排序
void InsertSort(int a[], int a_size) // 插入排序
{
int i, j;
int temp;
for (i = 1; i < a_size; i++)
{
temp = a[i];
for(j = i - 1; j >= 0; j--) // 每次找得到本次循环中最小的将它放到开头
{
if(temp < a[j])
{
a[j + 1] = a[j];
}
else
{
break;
}
}
a[j + 1] = temp;
}
}
4.希尔排序
void ShellSort(int a[], int len) // 希尔排序
{
int i, j;
int h, temp;
for (h = len / 2; h > 0; h = h / 2) // 分系列
{
for (i = h; i < len; i++) // 直接插入排序,步长为h
{
temp = a[i];
for(j = i - h; j >= 0; j -= h)
{
if(temp < a[j])
{
a[j + h] = a[j];
}
else
{
break;
}
}
a[j + h] = temp;
}
}
}
5.基数排序
void RadixCountSort(int *r, int *a, int len)
{
int i;
int *count = (int *)malloc(sizeof(int) * len);
for(i = 0; i < len; i++) // 所有置为零
{
count[i] = 0;
}
for(i = 0; i < 10; i++) // 确定每个桶中的数量,桶的编号在 0~9之间
{
++count[r[i]];
}
for(i = 1; i < len; i++) // 统计总数量
{
count[i] += count[i - 1];
}
int *sort = (int *)malloc(sizeof(int) * len);
for( i = len - 1; i >= 0; i--)
{
--count[r[i]]; // 使用一次数量减一
sort[count[r[i]]] = a[i];
}
for(i = 0; i < len; i++)
{
a[i] = sort[i];
}
free(sort); // 防止内存泄漏
free(count);
sort = count = NULL; // 指针指向的内存已经无效了,而指针没有被置空,引用一个非空的无效指针是一个未被定义的行为,也就是说不一定导致段错误,野指针很难定位到是哪里出现的问题,在哪里这个指针就失效了,不好查找出错的原因,所以调试起来会很麻烦。
}
void RadixSort(int *a, int len) // 基数排序
{
int i, ok = 0;
int radix_base = 1;
int *radix = (int *)malloc(sizeof(int) * len);
while(!ok)
{
ok = 1;
radix_base *= 10;
for(i = 0; i < len; i++) // 将各个位求出来便于分桶
{
radix[i] = a[i] % radix_base;
radix[i] /= radix_base / 10;
if(a[i] / (radix_base / 10) > 0)
{
ok = 0;
}
}
if(ok)
{
break;
}
RadixCountSort(radix, a, len);
}
free(radix); // 释放内存
radix = NULL; // 防止成为野指针
}
6.简单选择排序
void SelectSort(int a[], int len) // 简单选择排序
{
int i, j;
int temp = 0, flag = 0;
for(i = 0; i < len; i++)
{
temp = a[i]; // 当作最小值
flag = i;
for(j = i + 1; j < len; j++)
{
if(a[j] < temp)
{
flag = j;
temp = a[j];
}
}
if(flag != i) // 不是最大值,替换为最大值
{
a[flag] = a[i];
a[i] = temp;
}
}
}
7.堆排序
void AdjustMinHeap(int *a, int p, int len)
{
int temp;
int child;
for(temp = a[p]; 2 * p + 1 <= len; p = child)
{
child = 2 * p + 1;
if(child < len && a[child] > a[child + 1])
{
child++;
}
if(a[child] < temp)
{
a[p] = a[child];
}
else
{
break;
}
}
a[p] = temp;
}
void HeapSort(int a[], int len) // 堆排序
{
int i;
int temp;
for(i = len / 2 - 1; i >= 0; i--) // 改成为小顶堆
{
AdjustMinHeap(a, i, len - 1);
}
for(i = len - 1; i>= 0; i--)
{
temp = a[0]; // 将最小值放在最后
a[0] = a[i];
a[i] = temp;
AdjustMinHeap(a, 0, i - 1);// 堆中已经没有前一次找到的最小值,再次改造小顶堆,然后再一次去除最小的值
}
}
8.归并排序
void Merge(int a[], int l, int mid, int h) // 并拢
{
int i, j, k, n1, n2;
n1 = mid - l + 1;
n2 = h - mid ;
int *L = (int *)malloc(sizeof(int));
int *R = (int *)malloc(sizeof(int));
for(i = 0, k = l; i < n1; i++, k++)
{
L[i] = a[k];
}
for(i = 0, k = mid + 1; i < n2; i++, k++)
{
R[i] = a[k];
}
for(k = l, i = 0, j = 0; i < n1 && j < n2; k++) // 合并
{
if(L[i] < R[j])
{
a[k] = L[i];
i++;
}
else
{
a[k] = R[j];
j++;
}
}
// 可能其中一方数量多
if(i < n1) //
{
for(j = i; j < n1; j++, k++)
{
a[k] = L[j];
}
}
if(j < n2)
{
for(i = j; i < n2; i++, k++)
{
a[k] = R[i];
}
}
}
void MergeSort(int a[], int l, int h) // 归并排序
{
int middle;
int i;
if(l < h)
{
middle = (l + h) / 2;
// 不断分成两半
MergeSort(a, l, middle); // 前半部分
MergeSort(a, middle + 1, h); // 后半部分
// 将分开的再合起来
Merge(a, l, middle, h);
}
}