排序算法主要考点: 7种排序

              冒泡排序、选择排序、插入排序、shell排序、堆排序、快速排序、归并排序

以上排序算法是面试官经常会问到的算法,至于其他排序比如基数排序等等,这里不列举。

以下算法通过c++实现,开发工具Visual Studio 2012:代码下载


一、排序 :将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程

  排序分为内部排序、外部排序;

  若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序

  反之,若参加排序的记录数量很大,整个序列的排序过程不可能在内存中完成,则称此类排序问题为外部排序

   假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,

   即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的;

     否则称为不稳定的。

  1. 冒泡排序

    时间复杂度:最好的情况:表本身就是有序的,n-1次比较,时间复杂度为O(n);最坏的情况:表是逆序的,此时需要比较 1+2+3+...(n-1) = (n(n-1))/2,时间复杂度为O(n2)

    优点:简单、稳定

    缺点:慢,每次只能移动相邻两个数据,效率低

    c++实现:

 1             //冒泡排序
2 void Bubble_Sort(int *list,int count)
3 {
4 int flag = true;
5 int i = 0,j = 0;
6 for(i=0;i<=count&&flag;i++)
7 {
8 flag = false;
9 for(j=count -1;j>=i;j--)
10 {
11 if(list[j]<list[j-1])
12 {
13 swap(list[j],list[j-1]);
14 flag = true;
15 }
16 }
17 }
18
19 }

  2. 选择排序

    时间复杂度:O(n2)  :无论最好、最坏情况,都需要比较 (n(n-1))/2次,最好的情况交换次数为0,最坏的情况交换次数为n-1

    优点:交换移动数据次数相当少,性能上略优于冒泡排序

    缺点:效率低

    c++实现:

 1         //选择排序
2 void Select_Sort(int *list,int count)
3 {
4 int min,i,j;
5 for(i=0;i<count;i++)
6 {
7 min = i;
8 for(j=i+1;j<count;j++)
9 {
10 if(list[i]>list[j])
11 {
12 min = j;
13 }
14 }
15 if(min!=i)
16 {
17 swap(list[i],list[min]);
18 }
19
20 }
21 }

  3. 插入排序

    时间复杂度:最好情况:表本身就是有序的,比较次数是n-1次,没有移动记录,时间复杂度为O(n);最坏情况:表本身是无序的,比较次数是2+3+4+...+n = (n+2)(n-1)/2,移动次数也达到最大

    值为 (n+4)(n-1)/2次,所以时间复杂度为O(n2);如果根据概论相同的原则,平均比较和移动次数约为n2/4;

    优点:比选择,冒泡排序性能要好一些

    缺点:效率较低

    c++实现:

 1         //插入排序
2 void Insert_Sort(int *list,int count)
3 {
4 int temp;/*此处充当哨兵,不在list数组里面单独占一个单位*/
5 int i,j;
6 for(i=1;i<count;i++)
7 {
8 if(list[i]<list[i-1])
9 {
10 temp = list[i];
11 for(j=i-1;list[j]>temp&&j>=0;j--)
12 {
13 list[j+1] = list[j];
14 }
15 list[j+1] = temp;
16 }
17 }
18 }

  4. shell排序

    时间复杂度:O(n3/2)

    优点:跳跃式移动,使得排序效率提高

    缺点:不是一种稳定的排序算法

    c++实现:

 1        //shell排序
2 void Shell_Sort(int *list,int count)
3 {
4 int i,j;
5 int temp;
6 int increment = count;
7 do
8 {
9 increment = increment/3+1;
10 for(i = increment;i<count;i++)
11 {
12 if(list[i]<list[i-increment])
13 {
14 temp = list[i];
15 for(j=i-increment;j>=0&&list[j]>temp;j-=increment)
16 {
17 list[j+increment] = list[j];
18 }
19 list[j+increment] = temp;
20
21 }
22
23 }
24
25 }while(increment>1);
26 }

  5. 堆排序

    时间复杂度:O(nlogn)

    优点:性能上远远超过冒泡、选择、插入的时间复杂度O(n2)

    缺点:不是一种稳定的排序算法

    c++实现:

//调整为一个堆
void Heap_Adjust(int *list,int s,int m)
{
int temp = list[s];
for(int j=2*s+1;j<=m;j = 2*j+1)
{
if(list[j]<list[j+1]&&j<m)
{
j++;
}
if(temp>list[j])
break;
list[s] = list[j];
s = j;
}
list[s] = temp;
} //堆排序
void Heap_Sort(int *list,int len)
{
//创建一个大顶堆
for(int s = len/2-1;s>=0;s--)
{
Heap_Adjust(list,s,len-1);
} //排序
for(int i = len-1;i >= 1;i--)
{
swap(list[0],list[i]);
Heap_Adjust(list,0,i-1);
} }

    6. 归并排序

    时间复杂度:O(nlogn)

    优点:效率高、稳定

    缺点:占用内存较多

    c++实现:

//将有个有序数组排序
void Merge(int *list,int start,int mid,int end)
{
const int len1 = mid -start +1;
const int len2 = end -mid;
const int len = end - start +1;
int i,j,k; int * front = (int *)malloc(sizeof(int)*len1);
int * back = (int *)malloc(sizeof(int)*len2); for(i=0;i<len1;i++)
front[i] = list[start+i];
for(j=0;j<len2;j++)
back[j] = list[mid+j+1]; for(i=0,j=0,k=start;i<len1&&j<len2&&k<end;k++)
{
if(front[i]<back[j])
{
list[k] = front[i];
i++;
}else
{
list[k] = back[j];
j++;
}
}
while(i<len1)
{
list[k++] = front[i++];
}
while(j<len2)
{
list[k++] = back[j++];
} }
      //归并排序
void Merge_Sort(int *list,int count)
{
MSort(list,0,count-1);
}
        //归并排序
void MSort(int *list,int start,int end)
{ if(start<end)
{
int mid = (start+end)/2;
MSort(list,0,mid);
MSort(list,mid+1,end);
Merge(list,start,mid,end);
} }

  7. 快速排序

    时间复杂度:O(nlogn)(平均情况)

    优点:目前来说最快的排序算法,现在的快排算法大多是快速排序算法的改进算法

    缺点:跳跃式,不稳定

    c++实现:

        //快速排序
void Quick_Sort(int *list,int count)
{
Qsort(list,0,count-1);
}
       //快速排序
void Qsort(int *list,int low,int high)
{
int pivot;
if(low<high)
{
pivot =Partition(list,low,high);
Qsort(list,low,pivot-1);
Qsort(list,pivot+1,high);
} }
     int Partition(int *list,int low,int high)
{
int pivotKey;
pivotKey = list[low];
while(low<high)
{
while(low<high&&list[high]>=pivotKey)
{
high--;
}
swap(list[low],list[high]);
while(low<high&&list[low]<=pivotKey)
{
low++;
}
swap(list[low],list[high]);
}
return low;
}

附:

     void swap(int& a,int& b)
{
int temp = a;
a = b;
b = temp;
}

总结:排序:  插入排序类: 插入排序,希尔排序

        选择排序类: 选择排序,堆排序

        交换排序类: 冒泡排序,快速排序

        归并排序类: 归并排序

              

面试必备:排序算法汇总(c++实现)的更多相关文章

  1. 排序算法汇总(C/C++实现)

    前言:     本人自接触算法近2年以来,在不断学习中越多地发觉各种算法中的美妙.之所以在这方面过多的投入,主要还是基于自身对高级程序设计的热爱,对数学的沉迷.回想一下,先后也曾参加过ACM大大小小的 ...

  2. JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)

    1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...

  3. 面试10大算法汇总——Java篇

    问题导读 1 字符串和数组 2 链表 3 树 4 图 5 排序 6 递归 vs 迭代 7 动态规划 8 位操作 9 概率问题 10 排列组合 11 其他 -- 寻找规律 英文版 以下从Java角度解释 ...

  4. 面试10大算法汇总+常见题目解答(Java)

    原文地址:http://www.lilongdream.com/2014/04/10/94.html(为转载+整理) 以下从Java的角度总结了面试常见的算法和数据结构:字符串,链表,树,图,排序,递 ...

  5. Java常用的7大排序算法汇总

    1.插入排序算法 插入排序的基本思想是在遍历数组的过程中,假设在序号 i 之前的元素即 [0..i-1] 都已经排好序,本趟需要找到 i 对应的元素 x 的正确位置 k ,并且在寻找这个位置 k 的过 ...

  6. 七内部排序算法汇总(插入排序、Shell排序、冒泡排序、请选择类别、、高速分拣合并排序、堆排序)

    写在前面: 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素的随意序列,又一次排列成一个按keyword有序的序列.因此排序掌握各种排序算法很重要. 对以下介绍的各个排序,我们假定全部排 ...

  7. js排序算法汇总

    JS家的排序算法   十大经典算法排序总结对比 一张图概括: 主流排序算法概览 名词解释: n: 数据规模k:“桶”的个数In-place: 占用常数内存,不占用额外内存Out-place: 占用额外 ...

  8. 排序算法汇总(java实现,附源代码)

    整理系统的时候发现了原来写的各种算法的总结,看了一下,大吃一惊,那时候的我还如此用心,具体的算法,有的已经模糊甚至忘记了,看的时候就把内容整理出来,顺便在熟悉一下,以后需要的时候就可以直接过来摘抄了. ...

  9. C#实现所有经典排序算法汇总

    C#实现所有经典排序算法1.选择排序 class SelectionSorter { private int min; public void Sort(int[] arr) { ; i < a ...

随机推荐

  1. [考试总结]noip模拟11

    菜 这次考试又是骗了一堆分数... 然而其实一个正解都没写... \(T1\) 的方法说实话确实不是很正统.... 然而却 \(A\) 了... 在打完 \(T1\) 后拍了老长时间... 然后就耽搁 ...

  2. java开源项目学习

    http://jeecg-boot.mydoc.io/ 在线文档已切换至新地址: http://doc.jeecg.com Jeecg-Boot 是一款基于SpringBoot+代码生成器的快速开发平 ...

  3. 如何写好技术文档——来自Google十多年的文档经验

    本文大部分内容翻译总结自<Software Engineering at Google> 第10章节 Documentation. 另外,该书电子版近日已经可以免费下载了 https:// ...

  4. leetcode 987 二叉树的垂序遍历

    题目解析 题目意思很简单,就是给你一个二叉树,然后告诉你每个节点都是有位置信息的,即每个节点可以用(x,y)来表示.然后节点位置信息为(x,y)的节点的左节点位置为(x+1,y-1),右节点位置为(x ...

  5. 2020Android高级开发面试题以及答案整理,持续更新中~

    本篇收录了一些大厂面试中经常会遇到的经典面试题,并且我做好了整理分类.虽然今年的金九银十已经过去了,但是可以为明年的金三银四做准备啊,相信每一个跳槽季都有很多的前端开发者蠢蠢欲动,通过对本篇知识的整理 ...

  6. GitHub不再支持密码验证解决方案:SSH免密与Token登录配置

    今天提交代码,push到GitHub上,突然出现这个问题. remote: Support for password authentication was removed on August 13, ...

  7. Notepad++的NppFTP插件连接linux操作系统

    Notepad++的NppFTP插件连接linux操作系统 下载地址:https://notepad-plus-plus.org/downloads/v8.1.2/ 1.安装Npp_FTP插件 两种方 ...

  8. miniFTP项目实战五

    项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...

  9. OSI网络参考模型学习

    文章目录 一.计算机与网络的发展 1.1 批处理系统 1.2 分时系统 1.3 计算机之间的通信 1.4 基于分组交换技术的计算机网络 1.5 互联网时代的计算机网络 1.6 计算机网络中协议的规定 ...

  10. Xilinx约束学习笔记(一)—— 约束方法学

    <Xilinx约束学习笔记>为自己阅读 Xilinx 官方 UG903 文档后的学习笔记,大多数为翻译得来,方便大家学习. 1 约束方法学 1.1 组织约束文件 Xilinx 建议将时序约 ...