数据排序(一)

冒泡排序的改进:

为了标志在比较中是否进行了数据交换,设一个布尔量flag,在每趟比较前,将flag置为true,如果在比较中发生了数据交换,则将flag置为false,在一趟比较结束后,判断flag,如果它仍为true(表明该趟排序未发生数据交换)则排序结束,否则进行下一趟比较。

 1 const N=10;
 2 Var a: array[1..N] of integer;
 3   i,j,t: integer;flag:boolean;
 4 Begin
 5   for i:=1 to N do Readln(a[ i ]);
 6   for j:=1 to N-1 do begin
 7     flag:=true;
 8     for i:=1 to N-j do
 9       if a[ i ] < a[i+1] then begin
10         t:=a[i];a[i]:=a[i+1];a[i+1]:=t;
11         flag:=false;
12       end;
13     if flag then break;
14   end;
15   for i:=1 to N do write(a[ i ]:6);
16 end.

选择排序的改进:

由于每次交换两个数据元素要执行3个语句,过多的交换必定要花费许多时间。改进方案是在内循环的比较中找出最大元素的下标,在内循环结束时,才考虑是否交换。

 1 Const n=10;
 2 var a:array[1..n]of integer;
 3   i,j,t,k:integer;
 4 Begin
 5   for i:=1 to n do readln(a[i]);
 6   for i:=1 to n-1 do
 7     begin
 8       k:=i;
 9       for j:=i+1 to n do
10         if a[k]<a[j] then k:=j;
11       if k<>i then begin
12         t:=a[k];a[k]:=a[i];a[i]:=t;
13       end;
14     end;
15    for i:=1 to n do write(a[i]:5);
16 end.

竞赛中常用的几种排序算法:

  • 冒泡排序
  • 选择排序
  • 桶排序
  • 插入排序
  • 快速排序
  • 归并排序
  • 堆排序
  • 二叉排序树

桶排序

  • 桶排序的思想是若待排序的数据在一个明显的或可以预估的有限范围内,可设计有限个有序桶,每个桶装入一个值(当然也可以装入多个值),顺序输出各桶的值,将得到有序的序列。

    • 算法优点:时间效率高,时间复杂度仅为O(n),当然这个n不是待排序数据的数量,而是待排序数据的范围跨度;

      • 算法缺点:显然,当数据比较少,但范围跨度又比较大时,这个算法造成空间和时间上的巨大浪费。

       1 输入n个0~100之间的整数,由小到大排序输出。
       2 主要代码:
       3 for i:=0 to 100 do b[i]:=0;
       4 for i:=1 to n do
       5   begin
       6     read(k);
       7     inc(b[k]);
       8   end;
       9 for i:=0 to 100 do
      10   while b[i]>0 do begin
      11     write(i:6);
      12     dec(b[i]);
      13   end;

      示例一

       1 输入n个小写字母,按字典序输出。
       2 主要代码:
       3 for ch:=‘a‘ to ‘z‘ do b[ch]:=0;
       4 for i:=1 to n do
       5   begin
       6     read(c);
       7     inc(b[c]);
       8   end;
       9 for ch:=‘a‘ to ‘z‘ do
      10   while b[ch]>0 do begin
      11     write(ch:6);
      12     dec(b[ch]);
      13   end;

      示例二

插入排序

算法思想:有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)。是稳定的排序方法。
将n个元素的数列分为已有序和无序两个部分,如下所示:
{{a1},{a2,a3,a4,…,an}}
{{a1(1),a2(1)},{a3(1),a4(1) …,an(1)}}

{{a1(n-1),a2(n-1) ,…}, {an(n-1)}}
每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。

 1 //对r[1..n]按递增序进行插入排序,r[0]是监视哨
 2 procedure inssort(var r:arraytype);
 3 begin
 4   r[0]:=-maxint;
 5   for i:=2 to n do        //依次插入r[2],…,r[n]
 6   begin
 7     j:=i-1; x:=r[i];
 8     while x<r[j] do      //查找r[i]的插入位置
 9     begin
10       r[j+1]:=r[j];
11       j:=j-1;
12     end;
13     r[j+1]:=x;               //插入r[i]
14   end;
15 end;

插入排序效率分析:

  • 如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数加上 (n-1)次。平均来说插入排序算法的时间复杂度为O(n^2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。
  • 插入排序的一个优势是,待排序数据可以不必预先全部产生,允许对动态产生的数据进行排序,类似的还有二叉排序树和平衡二叉树等,但后两者效率更高,排序算法更复杂,我们将在以后的学习中介绍。
  • 插入排序还可以进行适当优化,采用二分法插入排序,在后面的学习中我们介绍过二分查找技术后,同学们可以自己改进插入排序的查找比较过程。

快速排序

基本思想: 快排的基本思想实质上是一种分治策略。在当前无序区R[1..H]中任取一个数据元素作为比较的"基准"(不妨记为 X),用此基准将当前无序区划分为左右两个较小的无序区:R[1..I-1]和 R[I+1..H],且左边的无序子区中数据元素均小于等于基准元素,右边的无序子区中数据元素均大于等于基准元素,而基准X则位于最终排序的位置上,即R[1..I-1]≤X.Key≤R[I+1..H](1≤I≤H),当 R[1..I-1]和R[I+1..H]均非空时,分别对它们进行上述的划分过程,直至所有无序子区中的数据元素均已排序为止。

为了防止快排在极端数据(例如数据原来就是有序的或者基本有序)情况下退化成冒泡排序,一般取无序区间中间位置的数作为比较基准,排序过程如下:
初 始 关键字    [38 65 97 49 76 13 27 48]
第一次交换后  [38 48 97 49 76 13 27 65]
第二次交换后  [38 48 27 49 76 13 97 65]
第三次交换后  [38 48 27 13 76 49 97 65] 交换后i=5,j=5,i=j
继续扫描,i=5,j=4,此时i>j,第一趟排序结束

【示例】:
初始关键字     [38 65 97 49 76 13 27 49]
一趟排序之后   [38 48 27 13] [76 49 97 65]
二趟排序之后   [38 13 27] [48] [49] [76 97 65]
三趟排序之后   [13] [38 27] [48] [49] [76 65] [97]
最后的结果       [13] [27] [38] [48] [49] [65] [76] [97]

 1 procedure sort(l,r:longint);
 2   var
 3     tmp,i,j,mid:longint;        //实际应用中,这里的变量可定义成全局变量以节省栈空间
 4   begin
 5     i:=l;
 6     j:=r;
 7     mid:=a[(i+j)div 2];        {将当前序列在中间位置的数定义为中间数基准}
 8     repeat
 9       while a[i]<mid do inc(i);        {在左半部分寻找比中间数大的数}
10       while a[j]>mid do dec(j);        {在右半部分寻找比中间数小的数}
11       if i<=j then            {若找到一组与排序目标不一致的数对则交换它们}
12         begin
13           tmp:=a[i];a[i]:=a[j];a[j]:=tmp;
14           inc(i);            {继续找}
15           dec(j);
16         end;
17     until i>j;            {注意这里不能有等号}
18     if l<j then sort(l,j);        {若序列有1个以上的无素,则递归搜索左右区间}
19     if i<r then sort(i,r);
20   end;
  • 快速排序的时间复杂度是O(nlog2n),速度快,但它是不稳定的排序方法。因此,就平均时间而言,快速排序是目前被认为是最好的一种内部排序方法。若初始记录序列按关键字有序或基本有序时,快速排序将退化为冒泡排序,其时间复杂度为O(n2)。
  • 如果我们选择标准关键字时采取一定的策略,就可以避免快速排序的退化,比如我们随机产生一个值x,以序列中的第x个位置的记录的关键字作为标准关键字,这样的随机化快速排序能很好地防止退化。一般都以序列中间位置的记录的关键字作为标准关键字,这样既可能简化代码,又能防止退化,是一种折中的常用方法。
  • 从时间上看,快速排序的平均性能优于前面讨论过的冒泡排序,选择排序、插入排序列方法,但快速排序需要一个栈空间来实现递归。
时间: 2024-08-07 14:11:46

数据排序(一)的相关文章

已知s.txt文件中有一个这样的字符串 请编写程序读取数据内容,把数据排序后写入 ss.txt文件

package cn.idcast5; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.Arrays; /* * 需求:已知s.txt文件中有一个这样

SQL从入门到基础 - 04 SQLServer基础2(数据删除、数据检索、数据汇总、数据排序、通配符过滤、空值处理、多值匹配)

一.数据删除 1. 删除表中全部数据:Delete from T_Person. 2. Delete 只是删除数据,表还在,和Drop Table(数据和表全部删除)不同. 3. Delete 也可以带where子句来删除一部分数据:Delete from T_Person where FAge>20. 二.数据检索 1. 执行备注中的代码创建测试数据表. 2. 简单的数据检索:select *from T_Employee(*表示所有字段) 3. 只检索需要的列:select FNumber

Python学习——数据排序方法

Python对数据排序又两种方法: 1. 原地排序:采用sort()方法,按照指定的顺序排列数据后用排序后的数据替换原来的数据(原来的顺序丢失),如: >>> data1=[4,2,6,432,78,43,22,896,42,677,12] >>> data1.sort() >>> data1 #原来的顺序被替换 [2, 4, 6, 12, 22, 42, 43, 78, 432, 677, 896] 2. 复制排序:采用sorted()内置函数,按照

21、任务十九——可视化数据排序

0.题目 基于任务18 限制输入的数字在10-100 队列元素数量最多限制为60个,当超过60个时,添加元素时alert出提示 队列展现方式变化如图,直接用高度表示数字大小 实现一个简单的排序功能,如冒泡排序(不限制具体算法),用可视化的方法表达出来 1.解答过程 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>task19</title> &

namenode示例 数据排序

2.0 数据排序 "数据排序"是许多实际任务执行时要完成的第一项工作,比如学生成绩评比.数据建立索引等.这个实例和数据去重类似,都是先对原始数据进行初步处理,为进一步的数据操作打好基础. 2.1 实例描述 对输入文件中数据进行排序.输入文件中的每行内容均为一个数字,即一个数据.要求在输出中每行有两个间隔的数字,其中,第一个代表原始数据在原始数据集中的位次,第二个代表原始数据. a.txt 7 4 3 b.txt 4 2 样例输出: 1 2 2 3 3 4 4 7 2.2 设计思路 这个

Berkeley DB使用SecondKey给数据排序的实现方法

Berkeley DB使用SecondKey给数据排序的 实现方法是本文我们主要要介绍的内容,在做项目的时候用到了nosql数据库BDB,借此机会研究了一下它的用法.它的官方示例和文档比较丰富,感觉比较 容易学习.在开发过程中出现了一个需求,要把数据根据插入时间遍历,个人认为通过第二主键(SecondKey)比较容易实现. 以下是我的基本实现过程: 1.在ValueBean中加入insertTime属性 public class ValueBean{ private String insertT

设计简单的后台管理的数据排序

场景: 前端需要展示一个列表如首页的轮播图后台需要能够控制列表数据的排序. 需求 自动规则 + 运营干预干预包括降低排名提升排名设定位置和新增item 实现 在Web后台管理系统中列表形式的数据排序功能是很常见的需求.要实现这类功能给数据表增加一个排序字段order越大排名越靠前数字相同时按照自动规则如id排序这样就可以实现了 id name order 1 tom 2 2 jack 3 3 bob 1 实际的排序显示为 jack tom bob 既然是后台那么主要的用户是公司的运营人员本着提高

DataSet 中的数据排序 及 DataRow装成DataTable

1.DataSet 中的数据排序 DataSet ds = new DataSet(); // 获取当前排口的数据 ds = _xiaobill.GetHistoryData(yinZiBianm, zhanDian, beginDate, endDate, dNum); DataTable dt = ds.Tables[0]; DataRow[] dt2 = dt.Select("1=1","数据时间 ASC "); DataRow[]装成DataTable Da

Hadoop mapreduce 数据去重 数据排序小例子

数据去重: 数据去重,只是让出现的数据仅一次,所以在reduce阶段key作为输入,而对于values-in没有要求,即输入的key直接作为输出的key,并将value置空.具体步骤类似于wordcount: Tip:输入输出路径配置. import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop

mongo数据排序和分页显示

数据排序 使用sort()1 升序-1 降序自然排序 数据插入的顺序$natural db.stu.drop(); db.stu.insert({"name":"张三","sex":"男","age":18,"score":70,"address":"河南"}); db.stu.insert({"name":"李四&q