读数据结构与算法分析

插入排序

核心:利用的是从位置0到位置P都是已排序的

所以从位置1开始排序,如果当前位置不对,则和前面元素反复交换重新排序

实现

void InsertionSort(ElementType A[], int N)
{
int i,P;
ElementType Tmp ;
for(P = 1;P < N;P++)
{
Tmp = A[P] ;
for(i = P;i > 0 && A[i-1] > Tmp;i--)
A[i] = A[i-1] ;
A[i] = Tmp ;
}
}


希尔排序

使用hk增量序列进行一趟排序后,对每个i都有

A[i] \leq A[i+hk]

重要性质:一个hk排序的文件在之后的排序中将保持hk排序性

实现

  • ht = [N / 2]
  • hk = [hk+1 / 2]
void ShellSort(ElmentType A[], int N)
{
ElementType Tmp ;
int i,j,Increment ;
for(Increment = N/2;Increment > 0;Increment /= 2)
for(i = Increment;i < N;i++)
{
Tmp = A[i] ;
for(j = i;j <= Increment;j -= Increment)
if(Tmp < A[j-Increment])
A[j] = A[j-Increment] ;
else
break ;
A[j] = Tmp ;
}
}

堆排序

基于原有的二叉堆

建立二叉堆,执行DeleteMax操作,储存至数组(节省空间可以倒序储存在当前数组)

实现

#define LeftChild(i) (2 * i + 1) ;
void Percdown(ElementType A[],int i,int N)
{
int Child ,i;
ElementType Tmp ;
for(Tmp = A[i]; LeftChild(i) < N-1;i = Child)
{
Child = LeftChild(i) ;
if(Tmp < A[Child])
A[i] = A[Chile] ;
else
break ;
}
A[i] = Tmp ;
} void HeapSore(ElementType A[],int N)
{
int i ;
for(i = N/2 ;i >= 0;i--)
Percdown(A,i,N) ; //建立二叉堆
for(i = N-1; i > 0; i--)
{
Swap(&A[0],&A[i]) ;
Percdown(A,0,i) ;
} }

归并排序

基本思想是合并两个已排序的表

实现

递归合并

void Msort(ElementType A[],ElementeType TmpArray[],int Left,int Right)
{
int Center ;
if(Left < Right)
{
Center = (Left + Right) /2 ;
Msort(A,TmpArray,Left,Right) ;
Msort(A,TmpArray,Center + 1,Right) ;
Merge(A,TmpArray,Left,Center + 1,Right) ;
}
}

驱动程序

void Mergesort(ElementType A[],int N)
{
ElementType *TmpArray ; TmpArray = malloc(N * sizeof(ElementType)) ;
if(TmpArray != NULL)
{
Msort(A,TmpArray,0,N-1) ;
free(TmpArray) ;
}
else
FatalError("内存不足") ;
}

合并函数

void Merge(ElementType A[],ElementType TmpArray[],int Lpos,int Rpos,int RightEnd)
{
int i,LeftEnd,NumElements,TmpPos ; LeftEnd = Rpos - 1;
TmpPos = Lpos ;
NumElement = RightEnd - Lpos + 1 ; while(Lpos <= LeftEnd && Rpos <= RightEnd)
if(A[Lpos] <= A[Rpos])
TmpArray[TmpPos++] = A[Lpos++] ;
else
TmpArray[TmpPos++] = A[Rpos++] ; while(Lpos <= LeftEnd)
TmpArray[TmpPos++] = A[Lpos++] ;
while(Rpos <= RightEnd)
TmpArray[TmpPos++] = A[Rpos++] for(i = 0;i < NumElement ;i++,RightEnd--)
A[RightEnd] = TmpArray[RightEnd] ;
}

快速排序

和归并排序一样都是分治递归算法,在小数组上效率并没有插入排序好

  1. 如果S中元素个数是0或1,则返回
  2. 取S中任一元素v,称为枢纽元
  3. 将S剩余的其它元素,分为两个不相交的集合
  4. 返回quicksort(S1),继续选择v,继续quicksort(S2) ;

实现

选取枢纽元

三数中值分割方法

ElementType Median3(ElementType A[],int Left,int Right)
{
int Center = (Left + Right) / 2 ; if(A[Left] > A[Center])
Swap(&A[Left],&A[Center]) ;
if(A[Left] > A[Right])
Swap(&A[Left],&A[Right]) ;
if(A[Center] > A[Right])
Swap(&A[Center],&A[Right]) ; Swap(&A[Center],&A[Right - 1]) ;
return A[Right - 1] ; }

主函数

#define Cutoff(3) ;

void Qsort(ElementType A[],int Left,int Right)
{
int i,j ;
ElementType Pivot ; if(Left + Cutoff <= Right)
{
Pivot = Midian3(A,Left,Right)
i = Left ; j = Right ;
for(;;)
{
While(A[++i] < Privot){}
While(A[--j] > Privot){}
if(i < j)
Swap(&A[i],&A[j]) ;
else
break ;
}
Swap(&A[i],&A[Right-1]) ; Qsort(A,Left,i-1) ;
Qsort(A,i+1,Right) ; }
else
InsertionSort(A + Left,Right - Left + 1) ;
}

驱动函数

void QuickSort(ElementType A[],int N)
{
Qsort(A,0,N-1) ;
}

总结

  • 对于一般的内部排序,选用的方法一般是插入排序、希尔排序和快速排序,根据输入来选择
  • 高度优化的快速排序在对于很少的输入也可能和希尔排序一样快

    对于快速排序,选取枢纽元十分关键

  • 堆排序比希尔排序要满
  • 插入排序一般用于较小的或接近排好序的输入
  • 归并排序在主存排序中不如快速排序那么好,但是合并时外部排序的中心思想

排序(C语言实现)的更多相关文章

  1. 选择排序_C语言_数组

    选择排序_C语言_数组 #include <stdio.h> void select_sort(int *); int main(int argc, const char * argv[] ...

  2. 计数排序(C语言版本)

    让我们来谈谈数的排序思维: 计数排序假定待排序的全部元素都是介于0到K之间的整数.计数排序使用一个额外的数组countArray.当中第i个元素是待排序数组array中值等于i的元素的个数.然后依据数 ...

  3. 排序算法——选择排序(js语言实现)

    选择排序:顾名思义选择,选择排序属于O(N^2)的排序算法,意思就是选择数组中的最小的拿出来放在第一位,然后再剩下的数里面,选择最小的,排在第二位,以此类推. 例如:8  3  4  5  6  2  ...

  4. 希尔排序——C语言

    希尔排序 希尔排序是插入排序的一种,又称“缩小增量排序”,希尔排序是直接插入排序算法的一种更高效的改进版本,关于插入排序可以看下这篇随笔:插入排序——C语言 (图片来源:https://www.cnb ...

  5. 排序(5)---------高速排序(C语言实现)

    继shell发明了shell排序过后呢,各位计算机界的大牛们又開始不爽了,为什么他能发明.我就不能发明呢.于是又有个哥们蹦出来了.哎...那么多排序,就木有一个排序是中国人发明的.顺便吐槽一下,一百年 ...

  6. 排序(4)---------希尔(shell)排序(C语言实现)

    由于考试耽搁了几天,不好意思~~~ 前面的介绍的三种排序算法,都属于简单排序,大家能够看下详细算法,时间复杂度基本都在0(n^2),这样呢,非常多计算机界.数学界的牛人就非常不爽了,他们在家里想啊想, ...

  7. [数据结构] 希尔排序 C语言程序

    //由小到大 //希尔排序 void shellSort( long int array[], int length) { int i; int j; int k; int gap; //gap是分组 ...

  8. 选择排序(直接排序)java语言实现

    class demo { public static void main(String[] args) { int[] arr={1,4,2,6,8,9,0,5,3,2,2,4,4,6,7,8}; f ...

  9. 高速排序java语言实现

    本博客不再更新,很多其它精彩内容请訪问我的独立博客 高速排序是非常重要的排序算法,可是我在学的时候发现网上没有特别好的样例所以自己动手写了一个. 自己动手丰衣足食. package sort; imp ...

  10. 排序(1)---------选择排序(C语言实现)

    选择排序的基本思想: 选择排序(Selection sort)是一种简单直观的排序算法. 它的工作原理例如以下.首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素 ...

随机推荐

  1. pymongo的安装和使用

    1.安装 MongoDB的python接口pymongo的安装方法有多种,如源码.easy_install.pip都可以.采用pip安装,很简单. pip install pymongo 安装完成后可 ...

  2. 软工之404 Note Found 队选题报告

    目录 NABCD分析引用 N(Need,需求): A(Approach,做法): B(Benefit,好处): C(Competitors,竞争): D(Delivery,交付): 初期 中期 个人贡 ...

  3. 当面试官问你sql优化的时候。。。

    当面试官问你有关sql优化的问题时,直接拿笔写给他: 8-select 9-distinct<column_list> 1-from left_table 3-<join_type& ...

  4. uboot 移植 要点

    1.第一 首先要  学会 shell 语法   比如 变量的 概念 变量的使用 ,if 语法  ,以及简单 IF 语法(与 或预算),以及  while for 循环 等等语法,才能看得懂 uboot ...

  5. 12c数据库重启后自动启动pdb

    由于最近管理12c数据库,创建了9个新的pdb.相对于以前11g版本每天一个一个的环境检查,方便了很多. 但是因为一次意外宕机,数据库重启.虽然数据库重启,但是管理的pdb确不能自动重启,所以需要手动 ...

  6. PE下安装官方WIN7

    进入PE后,用虚拟光驱 加载 win*.iso 文件后,运行安装程序setup.exe. 开始安装:

  7. DB数据源之SpringBoot+Mybatis踏坑过程实录系列(一)

    DB数据源之SpringBoot+MyBatis踏坑过程(一) liuyuhang原创,未经允许进制转载 系列目录 DB数据源之SpringBoot+Mybatis踏坑过程实录(一) DB数据源之Sp ...

  8. git 设置只输入一次用户名和密码

    https方式每次都要输入密码,非常不爽 按照如下设置可只输入一次 记住密码(默认15分钟): git config --global credential.helper cache 自己定义时间(一 ...

  9. MongoDB基础教程

    MongoDB 一.下载MongoDB数据库 1.进入MongoDB官网进行下载,网址:https://www.mongodb.com/. 2.下载完成后可进行安装,安装后,并有了MongoDB服务. ...

  10. keil编译运行错误,缺少error:#5:#include "core_cm3.h"

    用Keil  vision5编译时出现以下错误:error:  #5: cannot open source input file "core_cm3.h": No such fi ...