目录
辅助函数
//针对数组结构的算法
#include"c1.h"
#include "bo6堆.h"
#define MAX_NUM 20
#define cutoff 5 //阈值
typedef int ElementType;
int InputData(ElementType A[])
{//数据的读入
int i,len;
char s;
printf("请输入数据数量:\n");
scanf("%d",&len);
for (i = 0;i < len;i++)
{
printf("请输入第%d个数据:\n",i+1);
scanf("%d",&A[i]);
getchar(s);
}
return len;
}
void OutputData(ElementType A[],int len)
{//数据的输出
int i;
for (i = 0;i < len;i++)
printf("%3d",A[i]);
printf("\n");
}
void copyData(ElementType Source[],ElementType Target[],int n)
{//将source数组copy到target数组
int i;
for (i = 0;i < n;i++)
{
Target[i] = Source[i];
}
}
void swapElement(ElementType A[],int v,int w)
{//将A数组中下标为v和w的元素交换位置
ElementType temp;
temp = A[v];
A[v] = A[w];
A[w] = temp;
}
冒泡排序
void BubbleSort(ElementType A[],int n)
{//冒泡排序算法
int i,j;
bool key = true;
ElementType temp;
for (i = n;i > 0;i--)
{
for (j = 0;j < i-1;j++)
{
if (A[j] > A[j+1])
{
temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
key = false;
}
}
if (key)
break;
}
}
插入排序
void InsertSort(ElementType A[],int n)
{//插入排序算法(简单)
int i,j;
ElementType temp;
for (i = 1;i < n;i++)
{
temp = A[i];
for (j = i;j > 0;j--)
{
if (A[j-1] > temp)
A[j] = A[j-1];
else
break;
}
A[j] = temp;
}
}
折半插入排序
void BInsertSort(ElementType A[],int n)
{//折半插入排序算法
int i,j;
ElementType insertdata;
for (i = 1;i < n;i++)
{
insertdata = A[i];
if (insertdata < A[i-1])
{
int left = 0;
int right = i-1;
int center = (left+right)/2;
if (insertdata < A[0])
{
for (j = i;j > 0;j--)
A[j] = A[j-1];
A[0] = insertdata;
}
else
{
while (!(A[center] < insertdata && A[center+1] > insertdata))
{
if (insertdata > A[center])
{
left = center;
center = (left+right)/2;
}
else if (insertdata < A[center])
{
right = center;
center = (left+right)/2;
}
}
for (j = n;j > center+1;j--)
A[j] = A[j-1];
A[center+1] = insertdata;
}
}
}
}
2-路插入排序
void P2_InsertSort(ElementType A[],int n)
{//2-路插入排序
ElementType temp[MAX_NUM];
int i,k,first,final;
temp[0] = A[0];//初始化将A数组中的第一个元素取出来作为辅助数组的第一个参考元素
first = final = 0;//初始化i,j第一个元素即为最大元素,也为最小元素
for (i = 1;i < n;i++)
{
if (A[i] <= A[first])
{//比最小元素还小
first = (first - 1 + n)%n;
temp[first] = A[i];
}
else if (A[i] >= A[final])
{//比最大元素还大
final = (final + 1 + n)%n;
temp[final] = A[i];
}
else
{//介于最小元素和最大元素之间
k = (final + 1 + n)%n;
while (temp[(k - 1 + n)%n] > A[i])
{
temp[(k + n)%n] = temp[(k - 1 + n)%n];
k = (k - 1 + n)%n;
}
temp[(k + n)%n] = A[i];
final = (final + 1 + n)%n;
}
}
for (i = 0;i < n;i++)
A[i] = temp[(first + i + n)%n];
}
选择排序
void chooseSort(ElementType A[],int n)
{//选择排序算法(简单)
int i,j,minindex;
ElementType mindata;
for (i = 0;i < n-1;i++)
{
mindata = A[i];
minindex = i;
for (j = i;j < n;j++)
{
if (A[j] < mindata)
{
mindata = A[j];
minindex = j;
}
}
A[minindex] = A[i];
A[i] = mindata;
}
}
希尔排序
void shellSort(ElementType A[],int n)
{//希尔排序算法(原始序列)
int D,p,k;
int temp;
for (D = n/2;D > 0;D = D/2)
{
for (p = D;p < n;p++)
{
temp = A[p];
for (k = p;k >= D && A[k-D] > temp;k -= D)
A[k] = A[k-D];
A[k] = temp;
}
}
}
Hibbard增量序列
void shellHibbardSort(ElementType A[],int n)
{//希尔排序算法(Hibbard增量序列)
int i,D,p,k;
int temp,begin;
begin = 1;
while ((int)pow(2,begin) - 1 < n)
begin++;
begin--;
for (i = begin;i > 0;i--)
{
D = (int)pow(2,i) - 1;
for (p = D;p < n;p++)
{
temp = A[p];
for (k = p;k >= D && A[k-D] > temp;k -= D)
A[k] = A[k-D];
A[k] = temp;
}
}
}
Sedgewick增量序列
基于堆的选择排序
void chooseHeapSort(ElementType A[],int n)
{//基于堆的选择排序算法
BiTree T;
int i;
ElementType e;
T = (BiTNode*)malloc(sizeof(BiTNode));
CreateHeap(T);
for (i = 0;i < n;i++)
InsertTree(T,A[i]);
for (i = 0;i < n;i++)
{
DeleteTree(T,&e);
A[n-1-i] = e;
}
}
分而治之递归算法
void Merge(ElementType A[],ElementType TempA[],int L,int R,int RightEnd)
{//有序子列的归并
//L左边起始位置,R右边起始位置,RightEnd右边结束位置
int i,j,k = L;
int LeftEnd = R-1;//左边结束位置
i = L;
j = R;
while (i <= LeftEnd && j <= RightEnd)
{
if (A[i] < A[j])
{
TempA[k] = A[i];
i++;
k++;
}
else if (A[i] > A[j])
{
TempA[k] = A[j];
j++;
k++;
}
}
while (i <= LeftEnd)
{
TempA[k] = A[i];
i++;
k++;
}
while (j <= RightEnd)
{
TempA[k] = A[j];
j++;
k++;
}
//归并到TempA之后还要复制回去
for (i = RightEnd;i >= L;i--)
A[i] = TempA[i];
}
void Msort(ElementType A[],ElementType TempA[],int L,int RightEnd)
{//分而治之递归算法(基于有序子列的归并)
int center = (L + RightEnd)/2;
if (L < RightEnd)
{
Msort(A,TempA,L,center);
Msort(A,TempA,center+1,RightEnd);
Merge(A,TempA,L,center+1,RightEnd);
}
}
void Merge_sort(ElementType A[],int n)
{//统一函数接口
ElementType TempA[MAX_NUM];
int L = 0,RightEnd = n-1;
Msort(A,TempA,L,RightEnd);
}
分而治之非递归算法
void Merge1(ElementType A[],ElementType TempA[],int L,int R,int RightEnd)
{//有序子列的归并(针对非递归算法)
//L左边起始位置,R右边起始位置,RightEnd右边结束位置
//归并完之后,不把TempA复制给A,下一次从TempA归并到A上。
int i,j,k = L;
int LeftEnd = R-1;//左边结束位置
i = L;
j = R;
while (i <= LeftEnd && j <= RightEnd)
{
if (A[i] < A[j])
{
TempA[k] = A[i];
i++;
k++;
}
else if (A[i] > A[j])
{
TempA[k] = A[j];
j++;
k++;
}
}
while (i <= LeftEnd)
{
TempA[k] = A[i];
i++;
k++;
}
while (j <= RightEnd)
{
TempA[k] = A[j];
j++;
k++;
}
}
void Merge_pass(ElementType A[],ElementType TempA[],int n,int length)
{//length为当前有序子列的长度
int i,j;
for (i = 0;i <= n - 2*length;i += length*2)
Merge1(A,TempA,i,i+length,i+2*length-1);
if (i + length < n)
Merge1(A,TempA,i,i+length,n-1);
else
{
for (j = i;j < n;j++)
TempA[j] = A[j];
}
}
void Merge_sort_two(ElementType A[],int n)
{//分而治之非递归算法
int length = 1;
ElementType TempA[MAX_NUM];
while (length < n)
{
Merge_pass(A,TempA,n,length);
length *= 2;
Merge_pass(TempA,A,n,length);
length *= 2;
}
}
快速排序
ElementType Median3(ElementType A[],int left,int right)
{
int center = (left + right)/2;
if (A[left] > A[center])
swapElement(A,left,center);
if (A[left] > A[right])
swapElement(A,left,right);
if (A[center] > A[right])
swapElement(A,center,right);
swapElement(A,center,right-1);//把pivot存储到right-1位置
return A[right-1];
}
void QuickSort(ElementType A[],int left,int right)
{
if (cutoff <= right-left)
{//阈值需自己求出
int pivot;
int i = left,j = right-1;
pivot = Median3(A,left,right);
printf("pivot = %d\n",pivot);
while (true)
{
while (A[++i] < pivot) {}
while (A[--j] > pivot) {}
if (i < j)
swapElement(A,i,j);
else
break;
}
swapElement(A,i,right-1);//此时i位置左边的元素都比pivot小,把pivot换到i位置上
QuickSort(A,left,i-1);//为什么是i-1
QuickSort(A,i+1,right);//为什么是i+1
}
else
chooseSort(A,right-left+1);
}
void Quick_sort(ElementType A[],int n)
{//统一函数接口
QuickSort(A,0,n-1);
}
测试函数
void main()
{//对同一组数据进行多次算法测试
ElementType A[MAX_NUM];
ElementType B[MAX_NUM];
int num;
char option,handle;
int keynum;
bool key = true;
num = InputData(A);
OutputData(A,num);
while (key)
{
printf("选择算法名称:\n");
printf("a :冒泡排序 b :插入排序 c :折半插入排序 d: 2-路插入排序 \
e :选择排序 f :希尔排序 g :Hibbard增量序列 h: Sedgewick增量序列\
i :基于堆的选择排序 j :分而治之递归算法 k :分而治之非递归算法\
l :快速排序\n");
scanf("%c",&option);
copyData(A,B,num);
printf("这是原始序列:\n");
OutputData(B,num);
switch(option)
{
case 'a':
case 'A':
BubbleSort(B,num);//冒泡排序算法
break;
case 'b':
case 'B':
InsertSort(B,num);//插入排序算法
break;
case 'c':
case 'C':
BInsertSort(B,num);//折半插入排序算法
break;
case 'D':
case 'd':
P2_InsertSort(B,num);//2-路插入排序算法
break;
case 'E':
case 'e':
chooseSort(B,num);//选择排序算法
break;
case 'F':
case 'f':
shellSort(B,num);//希尔排序算法
break;
case 'G':
case 'g':
shellHibbardSort(B,num);//希尔排序算法(Hibbard增量序列)
break;
case 'H':
case 'h':
shellSedgewickSort(B,num);//希尔排序算法(Sedgewick增量序列)
break;
case 'I':
case 'i':
chooseHeapSort(B,num);//基于堆的选择排序算法
break;
case 'J':
case 'j':
Merge_sort(B,num);//分而治之递归算法(基于有序子列的归并)
break;
case 'K':
case 'k':
Merge_sort_two(B,num);//分而治之非递归算法(基于有序子列的归并)
break;
case 'L':
case 'l':
Quick_sort(B,num);//快速排序算法
break;
default:
break;
}
printf("这是排序之后的序列:\n");
OutputData(B,num);
printf("是否继续进行算法检测(1 :yes 0:no):\n");
scanf("%d%c",&keynum,&handle);
if (keynum == 0)
key = false;
}
}
表排序
数据本身较庞大,移动起来比较费时
- 间接排序
对指针进行排序
- 物理排序
必须对数据进行移动的时候
基数排序与桶排序
- 若数据范围M和待排数据数量N接近,直接进行桶排序
- 若数据范围M远大于待排数据数量N,则需进行基数排序。
- 若待排数据并非数字,那么需看情况选取关键字。
小白一枚,若有错误,还望各位多多批评指正。