• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C语言 > c++中八大排序算法

c++中八大排序算法

作者:真实的归宿 字体:[增加 减小] 来源:互联网 时间:2017-05-28

真实的归宿 通过本文主要向大家介绍了c++递归算法,c++算法,c++排序算法,c++数据结构与算法,银行家算法c++等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

概述

排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

我们这里说说八大排序就是内部排序。

当n较大,则应采用时间复杂度为O(nlog2n)的排序方法:快速排序、堆排序或归并排序序。

快速排序:是目前基于比较的内部排序中被认为是最好的方法,当待排序的关键字是随机分布时,快速排序的平均时间最短;

 1.插入排序—直接插入排序(Straight Insertion Sort)

基本思想:

将一个记录插入到已排序好的有序表中,从而得到一个新,记录数增1的有序表。即:先将序列的第1个记录看成是一个有序的子序列,然后从第2个记录逐个进行插入,直至整个序列有序为止。

要点:设立哨兵,作为临时存储和判断数组边界之用。

直接插入排序示例:

 如果碰见一个和插入元素相等的,那么插入元素把想插入的元素放在相等元素的后面。所以,相等元素的前后顺序没有改变,从原无序序列出去的顺序就是排好序后的顺序,所以插入排序是稳定的。

算法的实现:

void print(int a[], int n ,int i){ 
  cout<<i <<":"; 
  for(int j= 0; j<8; j++){ 
    cout<<a[j] <<" "; 
  } 
  cout<<endl; 
} 
 
 
void InsertSort(int a[], int n) 
{ 
  for(int i= 1; i<n; i++){ 
    if(a[i] < a[i-1]){        //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入 
      int j= i-1;  
      int x = a[i];    //复制为哨兵,即存储待排序元素 
      a[i] = a[i-1];      //先后移一个元素 
      while(x < a[j]){ //查找在有序表的插入位置 
        a[j+1] = a[j]; 
        j--;     //元素后移 
      } 
      a[j+1] = x;   //插入到正确位置 
    } 
    print(a,n,i);      //打印每趟排序的结果 
  } 
   
} 
 
int main(){ 
  int a[8] = {3,1,5,7,2,4,9,6}; 
  InsertSort(a,8); 
  print(a,8,8); 
} 
</div>

效率:

时间复杂度:O(n^2).

其他的插入排序有二分插入排序,2-路插入排序。

2. 插入排序—希尔排序(Shell`s Sort)

希尔排序是1959 年由D.L.Shell 提出来的,相对直接排序有较大的改进。希尔排序又叫缩小增量排序

基本思想:

先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。

操作方法:

1.选择一个增量序列t1,t2,…,tk,其中ti>tj,tk=1;
2.按增量序列个数k,对序列进行k 趟排序;
3.每趟排序,根据对应的增量ti,将待排序列分割成若干长度为m 的子序列,分别对各子表进行直接插入排序。仅增量因子为1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。

希尔排序的示例:

 算法实现:

我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数

即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至为1,最后使用直接插入排序完成排序。

void print(int a[], int n ,int i){ 
  cout<<i <<":"; 
  for(int j= 0; j<8; j++){ 
    cout<<a[j] <<" "; 
  } 
  cout<<endl; 
} 
/** 
 * 直接插入排序的一般形式 
 * 
 * @param int dk 缩小增量,如果是直接插入排序,dk=1 
 * 
 */ 
 
void ShellInsertSort(int a[], int n, int dk) 
{ 
  for(int i= dk; i<n; ++i){ 
    if(a[i] < a[i-dk]){     //若第i个元素大于i-1元素,直接插入。小于的话,移动有序表后插入 
      int j = i-dk;   
      int x = a[i];      //复制为哨兵,即存储待排序元素 
      a[i] = a[i-dk];     //首先后移一个元素 
      while(x < a[j]){   //查找在有序表的插入位置 
        a[j+dk] = a[j]; 
        j -= dk;       //元素后移 
      } 
      a[j+dk] = x;      //插入到正确位置 
    } 
    print(a, n,i ); 
  } 
   
} 
 
/** 
 * 先按增量d(n/2,n为要排序数的个数进行希尔排序 
 * 
 */ 
void shellSort(int a[], int n){ 
 
  int dk = n/2; 
  while( dk >= 1 ){ 
    ShellInsertSort(a, n, dk); 
    dk = dk/2; 
  } 
} 
int main(){ 
  int a[8] = {3,1,5,7,2,4,9,6}; 
  //ShellInsertSort(a,8,1); //直接插入排序 
  shellSort(a,8);      //希尔插入排序 
  print(a,8,8); 
} 
</div>

希尔排序时效分析很难,关键码的比较次数与记录移动次数依赖于增量因子序列d的选取,特定情况下可以准确估算出关键码的比较次数和记录的移动次数。目前还没有人给出选取最好的增量因子序列的方法。增量因子序列可以有各种取法,有取奇数的,也有取质数的,但需要注意:增量因子中除1 外没有公因子,且最后一个增量因子必须为1。希尔排序方法是一个不稳定的排序方法。

 3. 选择排序—简单选择排序(Simple Selection Sort)

基本思想:

在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

简单选择排序的示例:
 

操作方法:

第一趟,从n 个记录中找出关键码最小的记录与第一个记录交换;

第二趟,从第二个记录开始的n-1 个记录中再选出关键码最小的记录与第二个记录交换;

以此类推.....

第i 趟,则从第i 个记录开始的n-i+1 个记录中选出关键码最小的记录与第i 个记录交换,

直到整个序列按关键码有序。

算法实现:

void print(int a[], int n ,int i){ 
  cout<<"第"<<i+1 <<"趟 : "; 
  for(int j= 0; j<8; j++){ 
    cout<<a[j] <<" "; 
  } 
  cout<<endl; 
} 
/** 
 * 数组的最小值 
 * 
 * @return int 数组的键值 
 */ 
int SelectMinKey(int a[], int n, int i) 
{ 
  int k = i; 
  for(int j=i+1 ;j< n; ++j) { 
    if(a[k] > a[j]) k = j; 
  } 
  return k; 
} 
 
/** 
 * 选择排序 
 * 
 */ 
void selectSort(int a[], int n){ 
  int key, tmp; 
  for(int i = 0; i< n; ++i) { 
    key = SelectMinKey(a, n,i);      //选择最小的元素 
    if(key != i){ 
      tmp = a[i]; a[i] = a[key]; a[key] = tmp; //最小元素与第i位置元素互换 
    } 
    print(a, n , i); 
  } 
} 
int main(){ 
  int a[8] = {3,1,5,7,2,4,9,6}; 
  cout<<"初始值:"; 
  for(int j= 0; j<8; j++){ 
    cout<<a[j] <<" "; 
  } 
  cout<<endl<<endl; 
  selectSort(a, 8); 
  print(a,8,8); 
} 
</div>

简单选择排序的改进——二元选择排序

简单选择排序,每趟循环只能确定一个元素排序后的定位。我们可以考虑改进为每趟循环确定两个元素(当前趟最大和最小记录)的位置,从而减少排序所需的循环次数。改进后对n个数据进行排序,最多只需进行[n/2]趟循环即可。具体实现如下:

void SelectSort(int r[],int n) { 
  int i ,j , min ,max, tmp; 
  for (i=1 ;i <= n/2;i++) {  
    // 做不超过n/2趟选择排序  
    min = i; max = i ; //分别记录最大和最小关键字记录位置 
    for (j= i+1; j<= n-i; j++) { 
      if (r[j] > r[max]) {  
        max = j ; continue ;  
      }  
      if (r[j]< r[min]) {  
        min = j ;  
      }   
   }  
   //该交换操作还可分情况讨论以提高效率 
   tmp = r[i-1]; r[i-1] = r[min]; r[min] = tmp; 
   tmp = r[n-i]; r[n-i] = r[max]; r[max] = tmp;  
 
  }  
} 
</div>

4. 选择排序—堆排序(Heap Sort)

堆排序是一种树形选择排序,是对直接选择排序的有效改进。

基本思想:

堆的定义如下:具有n个元素的序列(k1,k2,...,kn),当且仅当满足

时称之为堆。由堆的定义可以看出,堆顶元素(即第一个元素)必为最小项(小顶堆)。
 若

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • C C++ 算法实例大全
  • c++中八大排序算法
  • 简单掌握桶排序算法及C++版的代码实现
  • C++德州扑克的核心规则算法
  • C++实现N个骰子的点数算法
  • C++线性时间的排序算法分析
  • C++遗传算法类文件实例分析
  • C++实现顺序排序算法简单示例代码
  • C++实现各种排序算法类汇总
  • 利用C++的基本算法实现十个数排序

相关文章

  • 2017-05-28C++实现的归并排序算法详解
  • 2017-05-28C++流操作之fstream用法介绍
  • 2017-05-28C语言简单实现计算字符个数的方法
  • 2017-05-28详解C++的模板中typename关键字的用法
  • 2017-05-28详解C语言中的#define宏定义命令用法
  • 2017-05-28Cocos2d-x学习笔记之Hello World源码分析
  • 2017-05-28基于WTL中使用双缓冲避免闪烁的解决方法
  • 2017-05-28基于C++中常见内存错误的总结
  • 2017-05-28有关C++中类类型转换操作符总结(必看篇)
  • 2017-05-28C++中实现把表的数据导出到EXCEL并打印实例代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • 详解C语言中index()函数和rindex()函数的用法
    • C++实现的链表类实例
    • C语言double和float 实例分析
    • C++模板类的用法
    • 基于一致性hash算法 C++语言的实现详解
    • C++之CNoTrackObject类和new delete操作符的重载实例
    • C语言中逻辑运算符与条件运算符的学习教程
    • 从汇编看c++的默认析构函数的使用详解
    • 详解C++中StringBuilder类的实现及其性能优化
    • C语言中char*和char[]用法区别分析

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有