选择显示字体大小

用游戏串起程序员的基本功之三


  前面我们学习了两种插入排序法,但当要排序的数组长度越长并且数值越不成顺序,比较和交换的次数就越多,效率越低。因此d.l.shell在1959年提出了缩小增量排序法(又叫希尔排序法),基本思想是:取一个间隔,将长序列分成若干短的子序列,对每个子序列进行直插排序;然后逐渐缩小间隔,重复以上过程,直到间隔为1。可以看到这种算法,较好的克服了直接插入排序法的不足。



  下面是示例:

8 7 4 3 6 1 //是要排序的数值,我们以一半的长度为间隔3
3 7 4 8 6 1 //第一次,取得3,小于前面的8,交换位置
3 6 4 8 7 1 //第二次,取得6,小于前面的7,交换位置
3 6 1 8 7 4 //第三次,取得1,小于前面的4,交换位置
1 6 3 4 7 8 //第四次,再缩小间隔,为2,取得1小于3,交换位置,取得7,大于前面的3,不变;取得8大于6,不变,取得4小于8,交换位置
1 3 4 6 7 8 //第五次,再缩小间隔,为1,取得6,大于1,不变;取得3小于6,交换位置;取得4,小于6,交换位置;取得7,大于前面的6,不变;取得8 ,大于7,不变

  以下是代码:

void paixu( ) //用希尔排序法,
{
 int n=13;// n为前后纪录位置的增量
 for (int z= n/2; z; z = z/2)//每次缩小增量
  for (int i = z; i < n; i++)//从增两大小开始比较
  {
   int temp = apai[i]; //将后一个备份
   for (int j = i; j >= z && temp < a[j - z]; j -= z) //与他在同一个子序列的数一个个的较
   {
    a[j] = a[j -z]; //如果小于,就交换
    }//end for
   a[j] = temp; //找到合适的插入点,放入其中
  }//end for
}//end


  我们再来看最后一种关于数组的排序方法,就是快速排序法,它是目前最快的一种排序的方法.它的基本思想是:通过一趟排序将待排序的记录分割为独立的两部分,其中一部分记录的数值均比另一部分记录的数值小,然后继续分别对这两部分进行排序,直到整个序列有序为止.

  具体做法: 任取待排序列的某个记录(我们可以取第一个数)作为基准,按照该数值大小,将整个序列分成两个序列——左侧的所有记录的数值都比基准小(或者相等),右侧的都比基准大,基准则放在两个子序列之间,显然这时基准放在了最后应该放置的位置。分别对左右子序列重复上面的过程,直到最后所有的记录都放在相应的位置。

  示例如下:

7 8 4 3 6 1 //是要排序的数值
1 8 4 3 6 //第一次,取得7,作为基准,1为right值,7>1,交换位置
1 4 3 6 8 //第二次, 8为left值,7<8,放到最后;
1 4 3 6 8 //第三次,left取得4,小于7,放到前面,
1 4 6 3 8 //第四次,right取6,小于7,放到前面
1 4 6 3 8 //第五次,left=right=3,小于7,放到前面,
1 4 6 3 7 8 //7放入合适位置,第一趟排序完成
//后面,在以1为基准排序
……
//直到成功

  代码如下:

void paixu(int a[],int low,int high;)//用快速排序法
{
 // low, high表示扫描的范围

 int pivot;//存放中心索引及其值的局部变量
 int scanup,scandown,mid;//用于扫描的索引
 if (high-low<=0) //如果数组中的元素少于两个,则返回
  return;
 else
  if(high-low==1) //如果有两个元素,对其进行比较
  {
   if(apai[high]<apai[low]) //如果后一个比前一个小,
    swap(apai[low],apai[high]);//那么交换位置
    return;
  }//end if
 mid=(low+high)/2;//取得中心索引
 pivot=apai[mid];//将中间索引的值,赋给pivot
 swap(apai[mid],apai[low]);//交换pivot及低端元素的值
 scanup=low+1;
 scandown=high;//初始化扫描索引scanup和scandown
 do{
  //从低端子表向上扫描,当scanup进入高端子表或遇到大于pivot的元素时结束.
  while(scanup<=scandown && apai[scanup]<=pivot)
   scanup++;
   //从高端子表向下扫描,当scandown遇到小于或等于pivot的元素时结束
  while(piovt<apai[scandown])
   scandown--;
   //如果两个索引还在各自的子表中,则表示两个元素错位,将两个元素换位
   if(scanup<scandown)
    swap(apai[scanup],apai[scandown]);
 }while(scanup<scandown);
 //将pivot拷贝到scandown位置,分开两个子表
  apai[low]=apai[scandown];
  apai[scandown]=pivot;
 //如果低端子表(low至scandown-1)有2个或更多个元素,则进行递归调用
 if(low<scandown-1)
  paixu(apai,low,scandown-1);
  //如果高端子表(scandown+1至high) 有2个或更多个元素,则进行递归调用
 if(scandown+1<high)
  paixu(apai, scandown+1, high);
}

  关于排序的问题已经够多了,就到这里吧,如果大家有兴趣,可以看已看这方面的书.下一节我们继续我们的游戏开发.


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons