Fork me on GitHub

数据结构---排序(1)

       放假10多天了,除去在外婆那里的3天,天天都在家看书。但是,寒假还是很多原定计划都没有完成,原因还是自己太懒惰了- -+。还好anytao的《你必须知道的.net》通了一遍,记得这本书是08年11月份借的,3个月断断续续的才看完,看的时候理论居多,动手的时候比较少,很多东西还是似懂非懂的。等有时间,再去实现它吧。笔记在本子上,以后再记到网上。

      《数据结构》是大二的课程,扔了一年以后,结果都忘得一干二尽了。乘着有点时间,重新温习一下。很久没写博客了,主要是自己写的东西对别人实在没什么帮助,也就没什么交流,也就失去了博客的意义了。这次就权当自己温习了。

      这里部分资料取自:http://www.hiahia.org/datastructure/main.htm =。=花了20元打印费,再不去那个地方了。

一、简介

       排序:顾名思义,就是将文件按一定的关键字递增或则递减的次序排列起来,形成有序。

       内排和外排:内排是指少量数据,在内存中进行排序。外排是指大量的数据,涉及到内、外存的交换。(主要还是讲内排)

       稳定性:如果存在多个关键字相同的记录,经过排序后这些记录之间的次序不变,就是稳定的。(以前一直没理解,现在也不是特别清晰)

       分类:插入排序、交换排序、选择排序、归并排序、分配排序(没用过)。

       操作:无非两种,一种是用if比较关键字的大小,第二种是改变或则移动记录(数组下标)。

       存储方式:也是两种,顺序表或则链表,我使用的都是顺序表- -,C#里面的链表应该是指向量吧。反正主要是温习排序的思路。就只选一种了。

       性能:执行时间、辅助空间、算法复杂度。

 

 二、插入排序

 2.1 直接插入排序

   思路:将第i个数据元素依次于i-1个数据元素比较,记录插入位置为j,将将j以后的数据元素后移。(书上不这么说的,我是方便自己理解。)

   步骤:书上的设计是利用循环产生随机数,然后插入适当位置,我将其改进为,从无序的数组中取数,思路是一样的。

           1.外层循环,将待排序列的数据依次取出。

           2.内层循环,与已排序列比较,记录此时待插入数据的位置。

           3.循环将上一步记录的位置之后的数据后移。

           4.将取出数据插入记录位置。

   描述:没办法画图,以后有机会补上。

   设计:

Code

 

可以明显看出,这种设计并不合理,首先空间复杂度达到O(n)。还一个需要改进的地方是,当第i次取出的数是最大数据时,算法依然从已排序的数组中的第0号位置开始比较。有没有一种更好的解决方案呢?于是乎想到第二种,insertSortCool();

思路差不多是一样的,但是步骤略有不同:

思路:将mat[0]看做有序,从mat[1..n-1]为无序,循环取出mat[1...n-1]中的数据,插入mat[0...i-1]中。

步骤:1.外层循环取数据,与mat[0...i-1]比较,如果mat[i]比mat[i-1]小,进入内层循环,否则取下一个数。

        2.如果mat[i]比mat[i-1]小,记录此时i-1的位置为j,并保存mat[i]中的数据为temp。

        3.内层循环,将数组j开始的数据后移,直到mat[j]中的数据小于temp,并且j必须大于等于0.

        4.此时j+1为temp插入的位置。

 

PS:第一种方法是自己根据书中的方法想出来的,第二种方法是参考出来的,学到了两个重要的思路。一是排序时比较操作与记录移动操作可以交替进行,二是从后往前排序的方法节约时间。

 

2.2希尔排序

希尔排序的实质是分组插入排序。

思路:取一个整数jump作为增量,将待排序列分为jump组,将每组进行插入排序;然后继续取第二个jump,重复分组排序,直至jump为1。

步骤:1.外层循环是jump的取值。

        2.内层循环是插入排序。

设计:

 

Code
posted @ 2009-02-05 14:03  idoku  阅读(250)  评论(0编辑  收藏  举报