【说明】这些代码部分参考严蔚敏老师的《数据结构》一书
【源代码】
//数据结构
#define MAX_LEN 40
typedef int KeyType;
typedef struct SQLIST{
KeyType key[MAX_LEN+1]; //关键字
int Length; //表实际长度
}SqList;
void PrintList(char * strKind,SqList list)
{
printf("%s",strKind);
for(int i=1; i<=list.Length; i++){
printf("%d ",list.key[i]);
}
printf("/n");
}
void MakeList(SqList &list)
{
printf("please input the length :");
scanf("%d",&list.Length);
while(list.Length > MAX_LEN){
printf("What you Input length is over Max %d/n",MAX_LEN);
printf("please input again : ");
scanf("%d",&list.Length);
}
printf("please input numbers :");
for(int i=1; i<=list.Length; i++){
scanf("%d",&list.key[i]);
}
}
//快速排序
//测试数据:5 2 6 9 7 1 3 4 0 8
// 11 55 68 2 35 78 9 87 -1 -58
//1,BubSort,升序排列
void BubSort(SqList &list)
{
KeyType temp;
for(int i=list.Length; i>=1; i--){
for (int j=2; j<=i; j++)
if(list.key[j-1] > list.key[j]){
temp = list.key[j-1];
list.key[j-1] = list.key[j];
list.key[j] = temp;
}
}
}
//2,Quick Sort,BubSort的升级,同样是升序排列
int Partition(SqList &list,int low,int high) //寻找划分处(剑影)
{
list.key[0] = list.key[low];
int pivotkey = list.key[low];
while(low < high){
while(low < high && list.key[high] >= pivotkey)
high--;
list.key[low] = list.key[high];
while(low <high && list.key[low] <= pivotkey)
low++;
list.key[high] = list.key[low];
}
list.key[low] = list.key[0];
return low;
}
void QuickSort(SqList &list,int low,int high)
{
if (low < high)
{
int pivotloc = Partition(list,low,high);
QuickSort(list,low,pivotloc-1);
QuickSort(list,pivotloc+1,high);
}
}
//选择排序 升序
//测试数据:5 2 6 9 7 1 3 4 0 8
// 11 55 68 2 35 78 9 87 -1 -58
// 0 256 0 25 86 9 -456 7 -56 100
//1,简单选择排序
int SelectMinKey(SqList list,int flag)
{
list.key[0] = list.key[flag];
int iMin = flag;
for(int i=flag; i<=list.Length; i++)
if (list.key[0] > list.key[i])
{
list.key[0] = list.key[i];
iMin = i;
}
return iMin;
}
void SelectSort(SqList &list)
{
KeyType temp;
for(int i=1; i<=list.Length; i++){
int j = SelectMinKey(list,i);
if(i != j){
temp = list.key[j];
list.key[j] = list.key[i];
list.key[i] = temp;
}
}
}
//2,堆排序:适合处理记录较大的数据
//堆定义:1,大根堆,K(i)>=K(2i)&&K(i)>=K(2i+1)
// 2,小根堆,K(i)<=K(2i)&&K(i)<=K(2i+1)
void HeapAdjust(SqList &list,int s,int m)
{
//前提条件:list中除list.key[s]之外均满足堆的定义
//目的 :重新调整list,使其满足大根堆的条件
KeyType rc = list.key[s];
for(int j=2*s; j<=m; j*=2){
if(j<m && list.key[j]<list.key[j+1])
j++;
if(rc > list.key[j])
break;
list.key[s] = list.key[j];
s = j;
}
list.key[s] = rc;
}
void HeapSort(SqList &list)
{
KeyType temp;
for(int i = list.Length/2; i>0; i--) //将list建成大根堆,从表后往前调整
HeapAdjust(list,i,list.Length);
for(i = list.Length; i>1; --i){ //每次将大根堆的第一个元素(即值最大)
temp = list.key[1]; //取出来放在末尾位置上(撇开已经排好的序列)
list.key[1] = list.key[i];
list.key[i] = temp;
HeapAdjust(list,1,i-1); //重新调整list为大根堆
}
}
//归并排序:升序
//测试数据:5 2 6 9 7 1 3 4 0 8
// 11 55 68 2 35 78 9 87 -1 -58
// 0 256 0 25 86 9 -456 7 -56 100
void Merge(SqList &SR,SqList &TR,int i,int m,int n)
{
for (int j=m+1,k=i; i<=m && j<=n; k++){
if(SR.key[i] < SR.key[j])
TR.key[k] = SR.key[i++];
else
TR.key[k] = SR.key[j++];
}
for( ; i<=m && k<=n; i++){
TR.key[k] = SR.key[i];
k++;
}
for( ; j<=n && k<=n; j++){
TR.key[k] = SR.key[j];
k++;
}
}
void MSort(SqList SR,SqList &TR1,int s,int t)
{
if(s ==t)
TR1.key[s] = SR.key[s];
else{
SqList TR2;
int m = (s+t)/2;
MSort(SR,TR2,s,m);
MSort(SR,TR2,m+1,t);
Merge(TR2,TR1,s,m,t);
}
}
void MergeSort(SqList &list)
{
MSort(list,list,1,list.Length);
}
//插入排序
//1,直接插入排序
void InsertSort(SqList &list)
{
for(int i=2; i<=list.Length; i++)
if(list.key[i] < list.key[i-1]){
list.key[0] = list.key[i];
list.key[i] = list.key[i-1];
for(int j=i-2; list.key[0]<list.key[j]; j--)
list.key[j+1] = list.key[j];
list.key[j+1] = list.key[0];
}
}
//2,希尔排序:对直接插入排序的一种优化(升级)
//又称:缩小增量排序
//排序描述:
//希尔排序的时间是增量序列的函数
void ShellInsert(SqList &list,int dk)
{
for (int i = dk+1; i<=list.Length; i++)
if(list.key[i] < list.key[i-dk]){
list.key[0] = list.key[i];
for (int j=i-dk; j>0 && list.key[0]<list.key[j]; j-=dk)
list.key[j+dk] = list.key[j];
list.key[j+dk] = list.key[0];
}
}
void ShellSort(SqList &list,int dlta[],int t)
{
//增量要求:
//在参考了河南大学,南京大学的张连堂教授和张博教授的《希尔排序最佳增量序列研究》后
//得出结论:当dlta[k] = 2`k-1;,即增量序列为...,2`k-1,...,15,7,3,1时排序较为理想
//严蔚敏老师的书上介绍了另外一个人的说法:dlta[k] = 2`(t-k+1)-1时排序的时间复杂度为O(n`(3/2))
for (int k=0; k<t; k++)
ShellInsert(list,dlta[k]);
}
【测试程序】
#include <stdio.h>
#include "AllKindofSort.h"
int main(int, char **, char **)
{
SqList lt;
MakeList(lt);
BubSort(lt);
PrintList("BubSort : ",lt);
//
SqList lt1;
MakeList(lt1);
QuickSort(lt1,0,lt1.Length);
PrintList("Quick Sort : ",lt1);
//
SqList lt2;
MakeList(lt2);
SelectSort(lt2);
PrintList("Simple Select Sort : ",lt2);
//
SqList lt3;
MakeList(lt3);
HeapSort(lt3);
PrintList("Heap Sort : ",lt3);
//
SqList lt4;
MakeList(lt4);
MergeSort(lt4);
PrintList("Merge Sort : ",lt4);
//
SqList lt5;
MakeList(lt5);
InsertSort(lt5);
PrintList("Direct Insert Sort : ",lt5);
//
SqList lt6;
int dt[3] = {7,3,1};
MakeList(lt6);
ShellSort(lt6,dt,3);
PrintList("Shell Sort : ",lt6);
return 0;
}
【测试结果】