//这里先写一个交换函数,避免后续重复书写。
void Swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
// 插入排序
void InsertSort(int* a, int n)
{
int left = 0;
int right = n;
for (int i = left+1; i < right; i++)
{
int j = i;
while (j>left&&a[j] < a[j - 1])
{
Swap(&a[j], &a[j - 1]);
j--;
}
}
}
// 希尔排序
void ShellSort(int* a, int n)
{
int left = 0;
int right = n;
int gap = n;
while (gap>1)
{
gap = gap / 3 + 1;//4,2,1
for (int i = left + gap; i < right; ++i)
{
if (a[i] < a[i - gap])
{
int tmp = a[i];
int j = i;
while (j>left&&tmp<a[j - gap])
{
a[j] = a[j - gap];
j = j - gap;
}
a[j] = tmp;
}
}
}
}
// 选择排序
int GetMinIndex(int* a, int left, int right)
{
int Min_Val = a[left];
int index = left;
for (int i = left + 1; i < right; ++i)
{
if (a[i] < Min_Val)
{
Min_Val = a[i];
index = i;
}
}
return index;
}
void SelectSort(int* a, int n)
{
int left = 0;
int right = n;
for (int i = left; i < right-1; ++i)
{
int index = GetMinIndex(a, i, right);
if (index != i)
Swap(&a[i], &a[index]);
}
}
// 堆排序
void AdjustDwon(int* a, int n, int start)
{
int i = start;
int j = 2 * i + 1;
int tmp = a[i];
while (j < n)
{
if (j + 1 < n&&a[j] < a[j + 1])
j = j + 1;
if (tmp < a[j])
{
a[i] = a[j];
i = j;
j = 2 * i + 1;
}
else
break;
}
a[i] = tmp;
}
void HeapSort(int* a, int n)
{
int left = 0;
int right = n;
int curpos = n / 2 - 1 + left;
while (curpos >= 0)
{
AdjustDwon(a, n, curpos);
curpos--;
}
int end = right - 1;
while(end > left)
{
Swap(&a[left], &a[end]); //出堆
AdjustDwon(a, end, 0);
end--;
}
}
// 冒泡排序
void BubbleSort(int* a, int n)
{
int left = 0;
int right = n;
for (int i = left; i < right-1; i++)
{
for (int j = 0; j < right - 1 - i; ++j)
{
if (a[j]>a[j + 1])
Swap(&a[j], &a[j + 1]);
}
}
}
// 快速排序递归实现
// 快速排序hoare版本
//hoare
int PartSort1(int* a, int left, int right)
{
int low = left, high = right - 1;
int key=a[low];
while (low < high)
{
while (low<high&&a[high]>key)
high--;
Swap(&a[high], &a[low]);
while (low < high&&a[low] <=key)
low++;
Swap(&a[low],&a[high]);
}
return low;
}
// 快速排序挖坑法
int PartSort2(int* a, int left, int right)
{
int low = left, high = right - 1;
int key = a[low];
while (low < high)
{
while (low<high&&a[high]>key)
high--;
a[low] = a[high];
while (low < high&&a[low] <= key)
low++;
a[high] = a[low];
}
a[low] = key;
return low;
}
// 快速排序前后指针法
//快慢指针法
int PartSort3(int* a, int left, int right)
{
int key = a[left];
int pos = left;
for (int i = pos + 1; i<right; ++i)
{
if (a[i] < key)
{
pos++;
if (pos != i)
{
Swap(&a[pos], &a[i]);
}
}
}
Swap(&a[left], &a[pos]);
return pos;
}
void QuickSort(int* a, int left, int right)
{
if (left >= right)
return;
int pos = PartSort3(a, left, right);
QuickSort(a, left, pos); // 左子序列
QuickSort(a, pos + 1, right); // 右子序列
}
// 归并排序递归实现
void _MergeSort(int *a, int left, int right, int *tmp)
{
if (left >= right)
return;
int mid = (left + right) / 2;
_MergeSort(a, left, mid, tmp); // 分解左边分支
_MergeSort(a, mid + 1, right, tmp); //分解右边分支
//开始归并
int begin1, end1, begin2, end2;
begin1 = left, end1 = mid;
begin2 = mid + 1, end2 = right;
int k = left; //
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] < a[begin2])
tmp[k++] = a[begin1++];
else
tmp[k++] = a[begin2++];
}
while (begin1 <= end1)
tmp[k++] = a[begin1++];
while (begin2 <= end2)
tmp[k++] = a[begin2++];
memcpy(a + left, tmp + left, sizeof(int) * (right - left + 1));
}
void MergeSort(int* a, int n)
{
int left = 0;
int right = n;
int* tmp = (int *)malloc(sizeof(int)*n);
_MergeSort(a, left, right - 1, tmp);
free(tmp);
}
// 计数排序
void CountSort(int* a, int n);
//注意:计数排序这里需要用到链表,所以这里我引入了一个List.h头文件。
#include"List.h"
#define K 3
#define RADIX 10
SList list[RADIX];
int GetKey(int value, int k) //2 3
{
int key;
while (k >= 0)
{
key = value % 10;
value /= 10;
k--;
}
return key;
}
void Distribute(int *ar, int left, int right, int k)
{
for (int i = left; i<right; ++i)
{
int key = GetKey(ar[i], k);
SListPushBack(&list[key], ar[i]);
}
}
void Collect(int *ar)
{
int k = 0;
for (int i = 0; i<RADIX; ++i)
{
SListNode *p = list[i].head;
while (p != NULL)
{
ar[k++] = p->data;
p = p->next;
}
}
//清除链表
for (int i = 0; i<RADIX; ++i)
SListClear(&list[i]);
}
void CountSort(int* a, int n)
{
for (int i = 0; i<RADIX; ++i)
SListInit(&list[i]);
int left = 0;
int right = n;
for (int i = 0; i<K; ++i)
{
//分发
Distribute(a, left, right, i);
//回收
Collect(a);
}
}
多种排序总结
最新推荐文章于 2024-03-29 10:00:00 发布