内部排序算法比较

来源:互联网 发布:cf淘宝代练会不会封号 编辑:程序博客网 时间:2024/05/05 15:09
排序算法是数据结构学科经典的内容,其中内部排序现有的算法有很多种,究竟各有什么特点呢?本文力图设计实现常用内部排序算法并进行比较。分别为起泡排序,直接插入排序,简单选择排序,快速排序,堆排序,针对关键字的比较次数和移动次数进行测试比较.

问题分析和总体设计
ADT OrderableList{
           数据对象:D={ai| ai∈IntegerSet,i=1,2,…,n,n≥0}
           数据关系:R1={〈ai-1,ai〉|ai-1, ai∈D, i=1,2,…,n}
           基本操作:
InitList(n)
  操作结果:构造一个长度为n,元素值依次为1,2,…,n的有序表。
Randomizel(d,isInverseOrser)
  操作结果:随机打乱
BubbleSort( )
  操作结果:进行起泡排序
InserSort( )
  操作结果:进行插入排序
SelectSort( )
  操作结果:进行选择排序
QuickSort( )
  操作结果:进行快速排序
HeapSort( )
  操作结果:进行堆排序
ListTraverse(visit( ))
  操作结果:依次对L种的每个元素调用函数visit( )
         }ADT  OrderableList

待排序表的元素的关键字为整数.用正序,逆序和不同乱序程度的不同数据做测试比较,
对关键字的比较次数和移动次数(关键字交换计为3次移动)进行测试比较.
要求显示提示信息,用户由键盘输入待排序表的表长(100-1000)和不同测试数据的组数(8-18).每次测试完毕,要求列表现是比较结果.
要求对结果进行分析.

详细设计
1、起泡排序
算法:核心思想是扫描数据清单,寻找出现乱序的两个相邻的项目。当找到这两个项目后,交换项目的位置然后继续扫描。重复上面的操作直到所有的项目都按顺序排好
bubblesort(struct rec r[],int n)
{
int i,j;
struct rec w;
unsigned long int compare=0,move=0;
for(i=1;i<=n-1;i++)
  for(j=n;j>=i+1;j--)
   {
    if(r[j].key<r[j-1].key)
     {
     w=r[j];
     r[j]=r[j-1];
     r[j-1]=w;
     move=move+3;
     }
    compare++;
   }
printf("/nBubbleSort compare= %ld,move= %ld/n",compare,move);
}


2、直接插入排序
算法:经过i-1遍处理后,L[1..i-1]己排好序。第i遍处理仅将L[i]插入L[1..i-1]的适当位置,使得L[1..i]又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较L[i]和L[i-1],如果L[i-1]≤ L[i],则L[1..i]已排好序,第i遍处理就结束了;否则交换L[i]与L[i-1]的位置,继续比较L[i-1]和L[i-2],直到找到某一个位置j(1≤j≤i-1),使得L[j] ≤L[j+1]时为止
insertsort(struct rec r[],int n)
{
int i,j;
unsigned long int compare=0,move=0;
for(i=2;i<=n;i++)
   {compare++;
    r[0]=r[i];
    move++;
    j=i-1;
   while(r[0].key {r[j+1]=r[j];
j--;
move++;
++compare;}
   r[j+1]=r[0];
   move++;
   }
  printf("/nInsertSort compare= %ld,move= %ld/n",compare,move);
}


3、简单选择排序
算法:首先找到数据清单中的最小的数据,然后将这个数据同第一个数据交换位置;接下来找第二小的数据,再将其同第二个数据交换位置,以此类推。
selectsort(struct rec r[],int n)
{
unsigned long int compare=0,move=0;
int i,j,k;
struct rec w;
for(i=1;i<=n-1;i++)
{      k=i;
     for(j=i+1;j<=n;j++)

     { if(r[j].key>r[k].key) {k=j; compare++; }
     w=r[i];
     r[i]=r[k];
     r[k]=w;
     move=move+3;

     }
}
printf("/nSelectSort compare= %ld,move= %ld/n",compare,move);
}


4、快速排序
算法:首先检查数据列表中的数据数,如果小于两个,则直接退出程序。如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。
通常分割点的数据是随机选取的。这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。而只要两个子列表的大小差不多

q(struct rec r[],int s,int t)
{
int i=s,j=t;
if(s<t)
{
  r[0]=r[s];    ++a;  c++;
  do{
while(j>i&&r[j].key>=r[0].key)
   {j--;
    ++a; }
if(i<j)
{ r[i]=r[j];
   i++;
   c++; }
while(i<j&&r[i].key<=r[0].key)
   {i++;
    ++a; }
if(i<j)
   { r[j]=r[i];
     j--;
     c++; }
    } while(i<j);
r[i]=r[0];
c++;
q(r,s,j-1);
q(r,j+1,t);
}
}


5. 堆排序
(1) 基本思想:
  堆排序是一树形选择排序,在排序过程中,将R[1..N]看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
(2) . 堆的定义: N个元素的序列K1,K2,K3,...,Kn.称为堆,当且仅当该序列满足特性:
       Ki≤K2i Ki ≤K2i+1(1≤ I≤ [N/2])

sift(struct rec r[],int l,int m)
{
int i,j;
struct rec w;
i=l; j=2*i;
w=r[i];
while(j<=m)
{
  if(j<m&&r[j].key<r[j+1].key)  { j++;
  }
  if(w.key<r[j].key)
  {
   r[i]=r[j];
   i=j;
   j=2*i;
   }
  else j=m+1;
  }
  r[i]=w;
}

heapsort(struct rec r[],int n)
{
  unsigned long int compare=-1,move=-1;
  struct rec w;
  int i;
  int a;
  for(i=n/2;i>=1;i--) a=sift(r,i,n);
  compare++;
  move++;

  for(i=n;i>=2;i--)
  {
    w=r[i];
    r[i]=r[1];
    r[1]=w;
    a=sift(r,1,i-1);
    compare+=a;
    move+=a;
   }
}


小结:
    1.学会使用随机函数randomize( ) 为数组赋初值要在头文件中添加#include
    2.在做此程序之前基本上是在理解了各种排序过程以后完成的
    3.对排序算法的总结:
(1)若n较小(如n≤50),可采用直接插入或直接选择排序。
     当记录规模较小时,直接插入排序较好;否则因为直接选择移动的记录数少于直接插人,应选直接选择排序为宜。
(2)若文件初始状态基本有序(指正序),则应选用直接插人、冒泡或随机的快速排序为宜;
(3)若n较大,则应采用时间复杂度为O(nlgn)的排序方法:快速排序、堆排序或归并排序。
     快速排序是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;
     堆排序所需的辅助空间少于快速排序,并且不会出现快速排序可能出现的最坏情况。这两种排序都是不稳定的。
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 割双眼皮后出血怎么办 双眼皮手术后出血怎么办 缝双眼皮开了怎么办 朋友网没了怎么办 压疮发生后怎么办 学籍账号已登录怎么办 护士学分不达标怎么办 高中学籍错了怎么办 定时器时间太短不够用怎么办? 考试时间不够用怎么办 感觉时间不够用怎么办 学习时间不够用怎么办 天天时间不够用怎么办 网贷骚扰通讯录怎么办 老被电话骚扰怎么办 对付广场舞噪音怎么办 普法平台考试不及格怎么办 假疫苗事件孩子怎么办 网上办生育证怎么办? 新生儿足跟血筛查没通过怎么办 新生儿听力筛查未通过怎么办 医药代表业绩差怎么办 网站诈骗被骗了怎么办 网贷利息过高怎么办 麦粒肿脓包不破怎么办 处方单丢了怎么办 深圳社保转外省怎么办 单位退休后医保怎么办 鼓楼医院就诊卡怎么办 2017个体户怎么办环评 查环保停工工人怎么办 林地己建房了怎么办 交不起环保罚款怎么办 单位没钱交社保怎么办 单位不缴医保怎么办 公司拖欠工资后注销怎么办 吸入纳米光触媒怎么办 溶解氧过低该怎么办 停水后来水浑浊怎么办 拉菜绿色通行证怎么办 烤箱下火太大怎么办