数据结构学习笔记06排序 (冒泡、插入、希尔)

前提
void X_Sort ( ElementType A[], int N )
  大多数情况下,为简单起见,讨论从小大的整数排序
  N是正整数
  只讨论基于比较的排序(> = < 有定义)
  只讨论内部排序
  稳定性:任意两个相等的数据,排序前后的相对位置不发生改变

1.冒泡排序

(从小到大排序)

物理意义:大泡泡往下沉,小泡泡往上冒

每次比较相邻两个泡泡,符合条件,交换位置,每一轮比较完,最大的泡泡沉到最底下。

最好情况:顺序T = O( N )
最坏情况:逆序T = O( N^2 )

稳定

 1 #include <stdio.h>
 2
 3 typedef int ElementType;
 4
 5 void BubbleSort(ElementType A[], int N)
 6 {
 7     for(int P = N-1; P >= 0; P--) {
 8         int flag = 0;
 9         for(int i = 0; i < P; i++) {
10             if( A[i] > A[i+1] ) {
11                 ElementType temp = A[i];    //swap A[i] A[i+1]
12                 A[i] = A[i+1];
13                 A[i+1] = temp;
14                 flag = 1;
15             }
16         }
17         if(flag == 0)
18             break;
19     }
20 }
21
22 int main()
23 {
24     int a[] = {34,8,64,51,32,21};
25     BubbleSort(a,6);
26     for(int i = 0; i < 6; i++)
27         printf("%d ",a[i]);
28
29     return 0;
30 } 

BubbleSort

2.插入排序

(从小到大排序)

和打扑克摸牌差不多,每次摸牌从最后往前依次进行比较,需插入的牌小,往前比较,找到合适位置插入。

最好情况:顺序T = O( N )
最坏情况:逆序T = O( N^2 )

 1 #include <stdio.h>
 2
 3 typedef int ElementType;
 4
 5 void InsertionSort(ElementType A[], int N)
 6 {
 7     int i;
 8     for (int P = 1; P < N; P++ ) {
 9         ElementType temp = A[P];     //取出未排序序列中的第一个元素
10         for (i = P; i > 0 && A[i-1] > temp; i-- )
11             A[i] = A[i-1];             //依次与已排序序列中元素比较并右移
12         A[i] = temp;
13     }
14 }
15
16 int main()
17 {
18     int a[] = {34,8,64,51,32,21};
19     InsertionSort(a,6);
20     for(int i = 0; i < 6; i++)
21         printf("%d ",a[i]);
22     return 0;
23 } 

InsertionSort

3.希尔排序

每5 3 1间隔数进行插入排序。

5 3 1成为增量序列。

  定义增量序列DM > DM-1 > … > D1 = 1
  对每个Dk 进行“Dk-间隔”排序( k = M, M-1, … 1 )
“Dk-间隔”有序的序列,在执行“Dk-1-间隔”排序后,仍然是“Dk-间隔”有序的

原始希尔排序DM = [N / 2]向下取整 , Dk = [D(k+1) / 2]向下取整

最坏情况: T =Ο( N^2 )

增量元素不互质,则小增量可能根本不起作用。

更多增量序列
  Hibbard 增量序列
    Dk = 2^k – 1 — 相邻元素互质
    最坏情况: T = O ( N^ 3/2 )
    猜想:Tavg = O ( N^ 5/4 )
  Sedgewick增量序列
    {1, 5, 19, 41, 109, … }
      9*4^i – 9*2^i + 1 或4^i – 3*2^i + 1
    猜想:Tavg = O ( N^ 7/6 ),Tworst = O ( N^ 4/3 )

 1 #include <stdio.h>
 2
 3 typedef int ElementType;
 4
 5 /* 原始希尔排序 */
 6 void Shell_Sort(ElementType A[], int N)
 7 {
 8     int i;
 9     for(int D = N/2; D > 0; D/=2) {
10         for(int P = D; P < N; P++) {
11             ElementType temp = A[P];
12             for(i = P; i >= D && A[i-D]>temp; i-=D)
13                 A[i] = A[i-D];
14             A[i] = temp;
15         }
16     }
17 }
18
19 /* 希尔排序 - 用Sedgewick增量序列 */
20 void ShellSort(ElementType A[], int N)
21 {
22      int Si, i;
23      /* 这里只列出一小部分增量 */
24      int Sedgewick[] = {929, 505, 209, 109, 41, 19, 5, 1, 0};
25
26      for ( Si = 0; Sedgewick[Si] >= N; Si++ )
27          ; /* 初始的增量Sedgewick[Si]不能超过待排序列长度 */
28
29      for (int D = Sedgewick[Si]; D > 0; D = Sedgewick[++Si])
30          for (int P = D; P < N; P++ ) {         //插入排序
31              ElementType temp = A[P];
32              for(i = P; i >= D && A[i-D]>temp; i-=D)
33                  A[i] = A[i-D];
34              A[i] = temp;
35          }
36 }
37
38 int main()
39 {
40     int a[] = {34,8,64,51,32,21};
41     Shell_Sort(a,6);
42     ShellSort(a,6);
43     for(int i = 0; i < 6; i++)
44         printf("%d ",a[i]);
45     return 0;
46 } 

ShellSort

时间: 2024-10-26 01:54:51

数据结构学习笔记06排序 (冒泡、插入、希尔)的相关文章

数据结构学习笔记06排序 (快速排序、表排序)

1.快速排序 不稳定 分而治之 找主元pivot,小于主元划分为一个子集,大于主元的划分为一个子集 然后进行递归 最好情况:每次主元正好中分,T(N) = O( NlogN ) 选主元 的方法有很多,这里用 取头.中.尾的中位数. 直接选A[0]为pivot,时间复杂度T ( N ) = O( N ) + T ( N–1 ) = O( N ) + O ( N–1 ) + T( N–2 ) = = O( N ) + O ( N–1 ) + …+ O( 1 ) = O( N^2 ) 随机取pivot

python 数据结构与算法之排序(冒泡,选择,插入)

目录 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 数据结构与算法: 算法: 数据结构 冒泡排序法 选择排序法 插入排序法 数据结构与算法之排序(冒泡,选择,插入) 为什么学习数据结构与算法: 计算机重要的几门课: 1.数据结构和算法 2.网络 3.操作系统 4.计算组成原理 数据结构与算法: 算法: 衡量算法的标准: 时间复杂度:就是程序代码执行的大概次数 小结: 时间复杂度是用来估计算法运行时间的一个式子(单位) 一般来说,时间复杂度高的算法比复杂度低的算法慢 常见的

小猪的数据结构学习笔记(二)

小猪的数据结构学习笔记(二) 线性表中的顺序表 本节引言: 在上个章节中,我们对数据结构与算法的相关概念进行了了解,知道数据结构的 逻辑结构与物理结构的区别,算法的特性以及设计要求;还学了如何去衡量一个算法 的好坏,以及时间复杂度的计算!在本节中我们将接触第一个数据结构--线性表; 而线性表有两种表现形式,分别是顺序表和链表;学好这一章很重要,是学习后面的基石; 这一节我们会重点学习下顺序表,在这里给大家一个忠告,学编程切忌眼高手低,看懂不代表自己 写得出来,给出的实现代码,自己要理解思路,自己

小猪的数据结构学习笔记(四)

小猪的数据结构学习笔记(四) 线性表之静态链表 --转载请注明出处:coder-pig 本章引言: 在二,三中中我们分别学习了顺序表中的线性表与单链表,线性表有点类似于 我们前面所学的数组,而单链表使用的最多的是指针,这里问个简单的问题, 如果是在以前没有指针的话,前辈先人们怎么实现单链表呢?大家思考下! 没有指针,那么用什么来代替呢?前辈先人们非常机智,想出了使用下标+游标的方式 来实现单链表的效果!也就是今天要讲的--静态链表! 当然你也可以直接跳过本章,因为有了单链表就没有必要用静态链表了

小猪的数据结构学习笔记(五)

小猪的数据结构学习笔记(五) 线性表之--循环链表                           --转载请注明出处:coder-pig 循环链表知识点归纳: 相关代码实现: ①判断是否为空表: ②单循环链表的存储结构 其实和单链表的结构是一样的! /*定义循环链表的存储结构*/ typedef struct Cir_List { int data; struct Cir_List *next; }Lnode; ③初始化循环单链表 代码如下: //1.循环链表的初始化 //表示一个元素,如

数据结构学习笔记之栈

栈(stack)  是限定仅在表尾进行插入或删除操作的线性表.因此,对栈来说,表尾端有其特殊含义,称为栈项(top),相应地,表头端称为栈底(bottom).不含元素的空表称为空栈. 栈有两种存储表示方法:顺序栈和链栈.顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素,同时附设指针top指示栈顶元素在顺序栈中的位置.通常的习惯做法是以top=0表示空栈,鉴于C语言中数组的下标约定从0开始,则当以C作描述语言时,如此设定会带来很大不便:另一方面,由于栈在使用过程

小猪的数据结构学习笔记(三)

小猪的数据结构学习笔记(三) 线性表之单链表 本章引言: 上一节中我们见识了第一个数据结构--线性表中的顺序表; 当你把操作的代码自己写几遍就会有点感觉了,如果现在让你写顺序表的 插入算法,你能够想出大概的代码么?如果可以,那么你就可以进入新的章节了; 否则,还是回头看看吧!在本节,我们将迎来线性表的链式表示--单链表 单链表和顺序表有什么优势和劣势呢?单链表的头插法和尾插法有什么不同呢? 请大家跟随笔者的脚步来解析线性表中的单链表把! 本节学习路线图 路线图解析: ①先要理解顺序表和单链表各自

数据结构学习笔记(1)-数据结构与算法

基本概念和术语 1.数据  数据元素  数据对象   数据结构 数据:在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称. 数据元素:是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理. 数据对象:是性质相同的数据元素的集合.是数据的一个子集. 数据结构:是相互之间存在一种或多种特定关系的数据元素的集合. 2.数据结构 数据结构分为逻辑结构和物理结构 2.1逻辑结构 逻辑结构表示数据之间的相互关系.通常有四种基本结构: 集合:结构中的数据元素除了同属于一种类型外,别

【数据结构学习笔记(C#描述)】(二)算法分析

由上一章的内容可知软件质量的重要特征之一就是能够高效的利用资源(运行效率),因此我们就要考虑如何创建出能够高效利用CPU及内存的数据结构与算法.而算法分析的目的就是为了让我们能够认识到算法对于资源的利用效率. 我们要想分析算法的效率,就需要找到一个评价算法效率的标准及方法. 一般我们如果能快速的利用CPU就会更好的节省时间,因此在时间层面上我们的评价标准就是时间复杂度,而如果我们能够较好的利用内存的话我们将会节省更多的内存空间,因此在空间层面上我们的评价标准就是空间复杂度. 所谓时间复杂度和空间