读数据结构与算法分析

插入排序

核心:利用的是从位置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. HDU 2307 贪心之活动安排问题

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2037 今年暑假不AC Time Limit: 2000/1000 MS (Java/Others)  ...

  2. spring boot 配置Rabbit

    单独安装Rabbit服务并设置启动,可以通过浏览器访问,一般访问地址是http://localhost:15672/ ,用户名密码看配置文件的用户名密码 1 实例化配置类注解 import org.s ...

  3. c#将List转换成DataTable(采用Emit)

    前段时间通过网上查找,使用emit将Datatable,DataReader转换成List<T>了.这是从数据库到展示. 但是最近整理Hikari(我写的数据库连接池),发现c#里面数据库 ...

  4. 复习Vue

    以前学过vue,但是工作中一直没有用到都忘记了最近在复习下正好做个笔记偶尔看看,(目前常更新,2018年6月25日) 1.指令 setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式. ...

  5. Java代码生成器CodeX4J介绍

    用代码生成器生成一些固定的或有规律的代码,可以有效的提高工作效率.我写了个开源的,放在了GitHub上,希望能对有需要的朋友有所帮助. GitHub代码地址https://github.com/jac ...

  6. (转载)SendKeys.Send()的使用

    SendKeys.Send() 使用SendKeys将键击和组合键击发送到活动应用程序.此类无法实例化.若要发送一个键击给某个类并立即继续程序流,请使用Send.若要等待键击启动的任何进程,请使用Se ...

  7. less的在线安装

    首先打开命令行窗口windonws+r输入cmd回车 1.确认是安装了node和less,在命令行输入“node -v”回车确认node是否安装,有版本信息则安装了,输入“lessc -v”回车确认l ...

  8. javascript node节点学习

    node节点学习 1 . 获取节点(元素)的方法 document.getElementById(); document.getElementsByTagName() document.getElem ...

  9. 全方面了解和学习PHP框架

    PHP框架是什么?    PHP框架提供了一个用以构建web应用的基本框架,从而简化了用PHP编写web应用程序的流程.这样不但节省开发时间,有助于建立更稳定的应用,而且减少了重复编码的开发.框架还可 ...

  10. linux-2.6.22.6内核启动分析之Makefile文件

    学习目标 分析Makefile文件,了解内核中的哪些文件被编译,如何被编译,连接时顺序如何确定! Linux内核源码中包含很多的Makefile文件,这些Makefile文件又包含其它的一些文件,比如 ...