我写了7个内部排序的方法,我想算他们的比较次数和移动次数

钟离雨菲 2013-12-21 09:08:56
我写了7个内部排序的方法,我想算他们的比较次数和移动次数,定义了两个数组,比较次数存在数组cmp[7]中,移动次数存在move[7]中,下面是程序,排序功能我都检测过了,没有问题,但是比较次数和移动次数我算的都不对,求大神们帮忙,如能帮忙,感激不尽啊
#define MAXSIZE 5000

typedef struct
{
int key;
}Datatype;

typedef struct
{
Datatype R[MAXSIZE+1];
int n;
}Sqlist;

int com[7]={0};
int move[7]={0};
//(1)简单选择排序
void SelectSort(Sqlist &S)
{
int i,j,k;
for(i=1;i<S.n;i++)
{
k=i;
for(j=i+1;j<=S.n;j++)
{
com[0]++;
if(S.R[k].key>S.R[j].key)
k=j;
}
if(i!=k)
{
S.R[0]=S.R[k];
S.R[k]=S.R[i];
S.R[i]=S.R[0];
move[0]+=3;
}
}
}

//(2)冒泡排序
void BubbleSort(Sqlist &S)
{
int i,j,k;
for(i=1;i<S.n-1;i++)
{
k=0;
for(j=1;j<=S.n-i;j++)
{
com[1]++;
if(S.R[j].key>S.R[j+1].key)
{
S.R[0]=S.R[j];
S.R[j]=S.R[j+1];
S.R[j+1]=S.R[0];
move[1]+=3;
k=1;
}
}
if(k==0)
break;
}
}

//(3)直接插入
void InsertSort(Sqlist &S)
{
int i,j;
for(i=2;i<=S.n;i++)
{
com[2]++;
if(S.R[i].key<S.R[i-1].key)
{
S.R[0]=S.R[i];
move[2]+=1;
for(j=i-1;S.R[0].key<S.R[j].key;j--)
S.R[j+1]=S.R[j];
S.R[j+1]=S.R[0];
move[2]+=2;
}
}
}

//(4)希尔排序

void ShellInsert(Sqlist &S,int dk)
{
int i,j;
for(i=dk+1;i<=S.n;i++)
{
com[3]++;
if(S.R[i].key<S.R[i-dk].key)
{
S.R[0]=S.R[i];
move[3]++;
for(j=i-dk;j>0&&(S.R[0].key<S.R[j].key);j-=dk)
{
com[3]++;
S.R[j+dk]=S.R[j];
move[3]++;
}
S.R[j+dk]=S.R[0];
move[3]++;
}
}
}
void ShellSort(Sqlist &S,int dlta[],int t)
{
int k;
for(k=0;k<t;k++)
ShellInsert(S,dlta[k]);
}


//(5)快速排序
int Partition(Sqlist &S,int low,int high)
{
int pivotkey;
pivotkey=S.R[low].key;
S.R[0]=S.R[low];
com[4]++;
while(low<high)
{
while(low<high&&S.R[high].key>=pivotkey)
{
high--;
// move[4]++;
}
S.R[low]=S.R[high];
move[4]++;
while(low<high&&S.R[low].key<=pivotkey)
{
low++;
// move[4]++;
}
S.R[high]=S.R[low];
move[4]++;

}
S.R[low]=S.R[0];
move[4]++;
return low;
}
void QSort(Sqlist &S,int low,int high)
{
int temp;
if(low<high)
{
temp=Partition(S,low,high);
QSort(S,low,temp-1);
QSort(S,temp+1,high);
}
}
void QuickSort(Sqlist &S)
{
QSort(S,1,S.n);
}

//(6)堆排序
void HeadAdjust(Sqlist &S,int s,int m)
{
Datatype rc;
int i,j;
rc=S.R[s];
for(j=2*s;j<=m;j*=2)
{
com[5]++;
if(j<m&&(S.R[j].key<S.R[j+1].key))
j++;
if(rc.key>=S.R[j].key)
break;
S.R[s]=S.R[j];
move[5]++;
s=j;
}
S.R[s]=rc;
}
void HeapSort(Sqlist &S)
{
Datatype temp;
for(int i=S.n/2;i>0;i--)
HeadAdjust(S,i,S.n);
for(i=S.n;i>1;i--)
{
temp=S.R[1];
S.R[1]=S.R[i];
S.R[i]=temp;
move[5]+=3;
HeadAdjust(S,1,i-1);
}
}

//(7)归并排序
void Merge(Datatype SR[],Datatype TR[],int i,int m, int n)
{
int l,j,k;
for(j=m+1,k=i;i<=m&&j<=n;++k)
{
com[6]++;
if(SR[i].key<SR[j].key)
{
TR[k]=SR[i++];
move[6]++;
}
else
{
TR[k]=SR[j++];
move[6]++;
}
}
if(i<=m)
{
for(l=0;l<=m-i;l++)
{
TR[k+l]=SR[i+l];
move[6]++;
}
}
if(j<=n)
{
for(l=0;l<=n-j;l++)
{
TR[k+l]=SR[j+l];
move[6]++;
}
}
}
void MSort(Datatype SR[],Datatype TR1[],int s,int t)
{
int m;
Datatype TR2[MAXSIZE+1];
if(s==t)
{
TR1[s]=SR[s];
move[6]++;
}
else
{
m=(s+t)/2;
MSort(SR,TR2,s,m);
MSort(SR,TR2,m+1,t);
Merge(TR2,TR1,s,m,t);
}
}
void MergetSort(Sqlist &S)
{
MSort(S.R,S.R,1,S.n);
}
...全文
524 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Vegertar 2013-12-21
  • 打赏
  • 举报
回复
STL用过没?比较谓词就是比较器了。 没有过STL,那么qsort呢?最后一个参数就是了。每调用一次,你就在函数里加1. 至于交换,事实上所有的移动都可以用swap组合出来,同样在swap函数里设一个计数器,调用一次就加1.
钟离雨菲 2013-12-21
  • 打赏
  • 举报
回复
引用 1 楼 Vegertar 的回复:
逆序数就是要排序的最小的比较次数。从决策树来看,比较次数最小的是归并排序。 移动次数和逆序数理论上是相等的,但是归并排序需要O(N)的空间,所以移动次数反而是快排最小,可以直接确定每个元素的最终位置。 楼主如果要计算这两个数值,不妨在比较器Compare和交换器Swap里分别加计数,不过像选择和冒泡貌似可以CompareAndSwap直接计数
可是这个什么和什么的比较器我不会用诶
Vegertar 2013-12-21
  • 打赏
  • 举报
回复
逆序数就是要排序的最小的比较次数。从决策树来看,比较次数最小的是归并排序。 移动次数和逆序数理论上是相等的,但是归并排序需要O(N)的空间,所以移动次数反而是快排最小,可以直接确定每个元素的最终位置。 楼主如果要计算这两个数值,不妨在比较器Compare和交换器Swap里分别加计数,不过像选择和冒泡貌似可以CompareAndSwap直接计数

64,682

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧