一、直接插入排序
直接插入排序:是一种最简单的排序方法,是插入排序的一种。
插入排序的基本思想是:在一个已经排好序的记录序列的基础之上,每次将一个待排序的记录有序地插入到已经排好序的记录序列之中,直到将所有待排序记录全部插入为止。
平均时间复杂度:O(n^2)
最坏时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void Sort(struct SortTable *S)//插入排序算法
{
int i,j;
for(i=2;i<=S->length;i++)
{
if(S->data[i] < S->data[i-1])
{
S->data[0]=S->data[i];
j=i-1;
while(S->data[0]<S->data[j])
{
S->data[j+1] = S->data[j];
j--;
}
}
S->data[j+1]=S->data[0];
}
}
void Print(struct SortTable *S)
{
int i;
printf("排序后:\n");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S);
Print(&S);
}
二、希尔排序
希尔排序:又称为缩小增量排序,因D.L.Shell与1959年提出而得名,是插入排序的一种。
希尔排序的基本思想:先取一个小于n的整数di为第一个增量,把全部记录分为d1个组,所有距离d1倍数的记录放在同一组中,在各组中进行直接插入排序;然后,取第二个增量d2<d1,重复上述分组和排序,直至所取的增量为dt=1(dt<dt-1<…<d2<d1),即所有记录放在同一组中进行直接插入排序。
平均时间复杂度:O(n^1.3)
最坏时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
int d[4]={5,3,1,0};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void Sort(struct SortTable *S,int d[])//希尔排序算法
{
int i,j,di,k=0;
do
{
di=d[k];
for(i=di+1;i <= S->length;i++)
if(S->data[i] < S->data[i-di])
{
S->data[0]=S->data[i];
for(j=i-di;j>0 && S->data[0]<S->data[j];j=j-di)
{
S->data[j+di]=S->data[j];
}
S->data[j+di]=S->data[0];
}
k++;
}while(di>1);
}
void Print(struct SortTable *S)
{
int i;
printf("排序后:\n");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S,d);
Print(&S);
}
三、冒泡排序
冒泡排序:是交换排序中最简单的一种。
冒泡排序的基本思想:首先将第一个记录的关键字与第二个记录的关键字进行比较,若为逆序,则交换两个记录,然后比较第二个记录和第三个记录的关键字,依此类推,直至比较低n-1个记录和第n个记录的关键字为止。上述过程为第一趟冒泡排序,其结果使关键字最大的记录被安置到最后一个记录的位置上,然后进行第二趟冒泡排序,对其n-1个记录进行同样的操作,其结果使关键字次大的记录被安置到第n-1个记录的位置上。依此类推,直至整个序列有序位置。
平均时间复杂度:O(n^2)
最坏时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入长度(<=30):");
scanf("%d",&S->length);
printf("请输入数据:\n");
for(i=0;i<S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void Sort(struct SortTable *S)
{
int i,j,t;
for(i=0;i<S->length;i++)
{
for(j=0;j<S->length-i-1;j++)
{
if(S->data[j]>S->data[j+1])
{
t=S->data[j+1];
S->data[j+1]=S->data[j];
S->data[j]=t;
}
}
}
}
void Print(struct SortTable *S)
{
int i;
printf("排序后:\n");
for(i=0;i<S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S);
Print(&S);
}
四、快速排序
快速排序:是交换排序的一种。
快速排序的基本思想:以某个记录为基准,通过一趟排序将待排序列分割为独立的两部分,其中第一部分所有记录的关键字均小于或等于基准记录的关键字,后一部分所有记录的关键字均大于或等于基准记录的关键字。将待排序列按关键字以基准记录分成两部分的过程,称为第一次划分。对各部分不断划分,直到整个序列按关键字有序排列。
平均时间复杂度:O(nlogn)
最坏时间复杂度:O(n^2)
空间复杂度:O(logn)
稳定性:不稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
int Partition(struct SortTable *S,int low,int high)//按基准进行分区
{
int i,j;
i=low,j=high;
S->data[0]=S->data[i];//暂存基准记录
while(i<j)
{
while(i<j && S->data[j]>S->data[0])//j向左扫描
j--;
S->data[i]=S->data[j];//将关键字小于基准的记录移动到基准前面
while(i<j && S->data[i] <= S->data[0])//i向右扫描
i++;
S->data[j]=S->data[i]; //将关键字大于基准的记录移动到基准后面
}
S->data[j]=S->data[0];//基准记录最终存放位置
return i;
}
void Sort(struct SortTable *S,int low,int high)//快速排序算法
{
int u;
if(low<high)
{
u=Partition(S,low,high);
Sort(S,low,u-1);//对左子表进行递归排序
Sort(S,u+1,high);//对右子表进行递归排序
}
}
void Print(struct SortTable *S)
{
int i;
printf("排序后:\n");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S,1,S.length);
Print(&S);
}
五、简单选择排序
简单选择排序:是一种简单的选择排序。
简单选择排序的基本思想:第一趟从所有的n个记录中,通过顺序比较各关键字的值,选取关键字值最小的记录与第一个记录交换;第二趟从剩下的n-1个记录中选取关键字值最小的记录与第二个记录交换,依此类推,第i趟排序从剩下的n-i个记录中选取关键字最小的记录,与第i个记录交换;经过n-1趟排序后,整个序列就成为了有序序列。
平均时间复杂度:O(n^2)
最坏时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:不稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void Sort(struct SortTable *S)
{
int i,j,k,d;
for(i=1;i<S->length;i++)
{
k=i;
for(j=i+1;j<=S->length;j++)
{
if(S->data[j]<S->data[k])
k=j;
}
if(k!=i)
{
S->data[0] = S->data[i];
S->data[i] = S->data[k];
S->data[k] = S->data[0];
}
printf("\n第%d趟排序结果:",i);
for(d=1;d<=S->length;d++)
{
printf("%4d",S->data[d]);
}
}
}
void Print(struct SortTable *S)
{
int i;
printf("\n最终排序后:");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S);
Print(&S);
}
六、堆排序
堆排序:是选择排序的一种。
堆排序的基本思想:有n个记录,首先将这n个记录按关键字建成堆,将堆顶元素输出,得到n个记录中关键字最小(或最大)的记录,将剩下的n-1个记录建成堆,输出堆顶元素,得到n个记录中关键字次小(或次大)的记录,如此反复,便得到一个按关键字有序排列的序列。
平均时间复杂度:O(nlogn)
最坏时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:不稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void sift(struct SortTable *S,int k,int m)//调整堆算法
{
int i,j;
i=k;
j=2*i;
S->data[0] = S->data[i];
while(j<=m)
{
if(j<m && S->data[j]<S->data[j+1])
j++;
if(S->data[0]<S->data[j])
{
S->data[i]=S->data[j];
i=j;
j=2*i;
}
else
break;
}
S->data[i]=S->data[0];
}
void Sort(struct SortTable *S)//堆排序算法
{
int k,i;
int w;
for(k=S->length/2;k>=1;k--)
sift(S,k,S->length);
printf("\n初始堆:");
for(i=1;i<=S->length;i++)
printf("%4d",S->data[i]);
for(k=S->length;k>=2;k--)
{
w=S->data[k];
S->data[k]=S->data[1];
S->data[1]=w;
sift(S,1,k-1);
}
}
void Print(struct SortTable *S)
{
int i;
printf("\n排序后:");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S);
Print(&S);
}
七、归并排序
归并排序:是将一个无序序列通过一系列合并产生一个有序序列,是利用“归并”技术来实现的。归并是指将若干个已经排好序的序列合并成一个有序序列。
归并排序的基本思想:设两个有序地子文件放在同一向量中相邻的位置r[low…m]和r[m+1…high]上,先将它们合并到一个局部暂存向量R1中。合并过程中,设置i,j,p三个指针,其初值分别指向这三个记录区的起始位置。合并时依次比较r[i]个r[j]的关键字,取关键字小小的记录复制到R1[p]中,然后将复制记录的指针i或j加1,且将指向复制位置的指针p加1。重复这一过程直至两个有序的子文件中有一个已经全部复制完毕为止,此时将另一个非空子文件的剩余记录依次复制到R1中。待合并完成后,将R1复制到r[low…high]中。
平均时间复杂度:O(nlogn)
最坏时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:稳定
#include <stdio.h>
#define MAXSIZE 30
struct SortTable
{
int length;
int data[100];
};
void Creat(struct SortTable *S)
{
int i;
printf("请输入待排序元素个数(<=30):");
scanf("%d",&S->length);
printf("请输入元素:\n");
for(i=1;i<=S->length;i++)
{
scanf("%d",&S->data[i]);
}
}
void Merge(struct SortTable *S,int low,int high,int m)
{
int temp[100];//temp为临时数组,存放待排序的元素
int i,j,k;
for(i=low;i <= high;i++)
{
temp[i] = S->data[i];
}
i=low;j=low+m;k=low;
while(i<low+m && j<=high)
{
if(temp[i] <= temp[j])
{
S->data[k++] = temp[i++];
}
else
{
S->data[k++] = temp[j++];
}
}
if(i >= low+m)
{
while(j <= high)
S->data[k++] = temp[j++];
}
else
{
while(i < low+m)
S->data[k++] = temp[i++];
}
}
void Sort(struct SortTable *S)//归并排序算法
{
int length,low,high;
low = 1;
length = 1;
while(length < S->length)
{
high = (S->length < low+2*length-1) ? S->length:low+2*length-1;
Merge(S,low,high,length);
if(high + length < S->length)
low = high + 1;
else
{
length = length * 2;
low = 1;
}
}
}
void Print(struct SortTable *S)
{
int i;
printf("\n最终排序后:");
for(i=1;i<=S->length;i++)
{
printf("%4d",S->data[i]);
}
printf("\n");
}
void main()
{
struct SortTable S;
Creat(&S);
Sort(&S);
Print(&S);
}