直接插入排序 :每趟将一个待排序的关键字按照其值得大小插入到已经排好得部分有序序列的适当位置上,直到所有待排关键字都被插入到有序序列为止;

void InsertSort(int R[], int n) {int i, j, temp;for (int i = 0; i < n; i++) {temp = R[i]; //将待插入关键字暂存于temp中j = i - 1;//下面这个循环完成了从待排关键字之前得关键字开始扫描,如果大于待排关键字,则后移一位while (j >= 0 && temp < R[i]) {R[j + 1] = R[j];   //每个后移--j;}R[j + 1] = temp; //找到插入位置,将temp中暂存得关键字插入}
}

折半插入排序:每趟将一个待排序的关键字按照其值得大小插入到已经排好得部分有序序列的适当位置上,直到所有待排关键字都被插入到有序序列为止和直接插入得区别在于查找方式不同

希尔排序:希尔排序又称之为缩小增量排序,其本质还是插入排序,只不过是将待排序列按照某种规则分成几个子序列,分别对这几个子序列进行直接插入排序。这个规则的体现就是增量的选取.希尔排序的时间复杂度为O(n*logn)

void Shellsort(int Array[], int n){int d = n / 2;//设置起始增量while (d >= 1){//增量为1时排序结束for (int k = 0; k < d; ++k){//遍历所有的子序for (int i = k + d; i < n; i += d){//对每个子序进行插入排序int temp = Array[i];int j = i - d;while (j >= k && Array[j] > temp){Array[j + d] = Array[j];j -= d;}Array[j + d] = temp;}}d = d / 2;//缩小增量}
}

冒泡排序

void BubbleSort(int R[], int n){//默认待排序关键字为整型int i = 0, j = 0, flag = 0;int temp;for (int i = n - 1; i >= 1; --i){flag = 0;//变量flag用来标记本堂排序是否发生了交换for (j = 0; j < i; ++j) {if (R[j - 1] > R[j]) {temp = R[j];R[j] = R[j - 1];R[j - 1] = temp;flag = 1;//如果没有发生交换,则flag的值为0,;如果发生了交换,flag的值改为1}}if (0 == flag)//一趟排序过程中如果没有发生关键字交换,则证明序列有序,排序结束return;}
}

快速排序 :也是交换类的排序,它通过多次划分操作实现排序。以升序为例,其执行流程可以概括为:每一趟选择当前所有子序列中的一个关键字(通常是第一个)作为枢轴,将子序列中比枢轴小的移到枢轴的前边,比枢轴大的移动到枢轴的后边;当本趟所有的子序列都被枢轴以上述规则划分完毕后会的到新的一组更短的子序列,它们成为下一趟划分的初始序列集。快速排序的算法思想基于分治思想的,其平均时间复杂度为O(n*logn),最坏时间复杂度为O(n*n)

void QuickSort(int R[], int low, int high){//对从R[Low]到R[High]的关键字进行排序int temp = 0;int i = low, j = high;if (low < high){temp = R[low];//下面这个循环完成了一趟排序,即数组中小于temp的关键字放在左边,大于temp的关键字放在右边。左边和右边的分界点就是temp的最终位置while (i < j){while (i < j && R[j] >= temp) {//先从右往左扫描,找到第一个小于temp的关键字--j;}if (i < j){ //这个判断保证退出上面的while循环是因为R[j] < temp,而不是因为 i>= j退出循环的,此步非常重要切忌将其忽略R[i] = R[j];//放在temp左边++i;//i右移一位}while (i < j && R[i] <= temp) {//从右往左扫描,找到一个大于temp的关键字++i;}if (i < j){R[j] = R[i];//放在tem的左边--j;//j右移一位}}R[j] = temp;//将temp放在最终的位置上QuickSort(R, low, i - 1);//递归的对temp左边的关键字进行排序QuickSort(R, i + 1, high);//递归的对temp右边的关键字进行排序}
}

简单选择类排序:选择类排序的主要动作是“选择”。简单选择采用最简单的选择方式,从头至尾扫描序列,选出最小的一个关键字,和第一个关键字交换,接着从剩下的关键字中继续这种选择和交换,最终使序列有序

void SelectSort(int R[], int n){int i = 0, j = 0, k = 0;int temp = 0;for (i = 0; i < n; ++i){k = i;//下面这个循环是算法的关键,它从序列中挑选出最小的一个关键字for (j = i + 1; j < n; ++j){if (R[k] > R[j])k = j;}//下面三句完成最小关键字与无序序列的第一个关键字的交换temp = R[i];R[i] = R[k];R[k] = temp;}
}

堆排序 是一种完全二叉树,这颗二叉树满足:任何一个非叶结点的值都不大于(或小于)其左右孩子结点的值。若父亲大孩子小,这样的堆称之为大顶堆;若父亲小孩子大称为小根堆。根据堆的定义可以知道,代表堆的这颗完全二叉树的根结点是最大的(或者最小的),因此将一个无序的序列调整为一个堆,就可以找到这个序列的最大值(或者最小)的值,然后将找出的值交换到这个序列的最后(或最前),这样有序序列关键字增加1个,无序序列中的关键字减少1个,对新的无序序列重复这样的操作,就实现了排序。这就是堆排序的思想

堆排序中最关键的操作是将序列调整为堆。整个排序的过程就是通过不断调整,使得不符合堆定义的完全二叉树变为符合堆定义的完全二叉树堆的插入关键字:需要在插入结点之后保持堆的性质,即完全二叉树形态与父大子小性质(以大根堆为例),
因此需要先将要插入的结点X放在最底层的最右边,插入后满足完全二叉树的特点,然后把X依次向上调整到合适位置上以满足父大子小的性质堆中删除结点:删除堆中一个结点时,原来的位置就会出现一个孔,填充这个孔的方法就是:
把最底层最右边的叶子值赋给该孔并下调到合适的位置,最后把该叶子结点点删除堆排序执行过程描述(以大根堆为例):
    1)从无序序列所确定的完全二叉树的第一个非叶子结点开始,从左至右,从上至下,对每个结点进行调整,最终得到一个大根堆 对结点的调整方法:将当前结点(假设为A)的值与其孩子结点进行比较,如果存在大于A的值的孩子结点。则从中挑出最大的一个与A进行交换。当A来到下一层的时候重复上述过程,直到A的孩子结点的值都小于A的值为止。
    2)将当前的无序序列中的第一个关键字,反应在树的根结点(假设为B)与无序序列中的最后一个关键字交换(假设为C)。B进入有序序列,达到最终位置。无序序列中的关键字个数减少1个,有序序列中的关键字个数增加1个,此时只有结点C可能不满足堆的定义,对其进行调整
    3)重复上述第2)步,直到无序序列中的关键字个数为1时结束排序

//本函数完成在数组R[Low]到R[High]的范围内对在位置Low上的结点进行调整
void Sift(int R[], int Low, int High){//这里关键字的存储设定为从数组下标为1开始int i = Low, j = 2 * i;//R[j]是R[i]的左孩子int temp = R[i];while (j <= High){if (j < High && R[j] < R[j + 1]) {//若右孩子较大,则把j指向右孩子++j;//j变为 2*i+1}if (temp < R[j]){R[i] = R[j];//将R[j]调整到双亲结点的位置上i = j;j = 2 * i;//修改i和j的值,以便继续向下调整}else break;}R[i] = temp;//被调整结点的值放入最终位置
}
//堆排序函数
void HeapSort(int R[], int n){int i = 0;int temp = 0;for (i = n / 2; i >= 1; --i) {//初始化堆Sift(R, i, n);}for (i = n; i >= 2; --i){//进行n-1次循环完成堆排序//下面三句换出了根结点中的关键字,将其放入最终的位置temp = R[1];R[1] = R[i];R[i] = temp;Sift(R, 2, i - 1);//在减少了1个关键字的无序序列中进行调整}
}

堆排序算法所需的空间复杂度为O(1),这是它相对于归并排序的优点。时间复杂度在任何情况下均为O(n*logn),
这是它相对于快速排序的最大优点, 快速排序最坏的时间复杂度为O(n*n)。
堆排序适用场景是关键字数目特别多的情况下,典型的例子是从10000个关键字选出前10个最小的。这种情况下用堆排序最好。
如果关键字数目较少,则不建议使用堆排序
STL中已经写好了堆排序,一般如果是自己在实践中需要用的是由直接调用STL相关的即可

二路归并排序:先将整个序列分为两半,对每一半分别进行归并排序,将得到两个有序序列,然后将这两个序列归并成一个序列即可。

void merge(int A[], int low, int mid, int high) {int i, j, temp;for (int i = mid; i <high; ++i) { //将A[m,m+n-1]插入到A[0,m-1]中 //逐个插入temp = A[i];for (j = i - 1; j >= low && temp < A[j]; --j) { //寻找一个合适的位置A[j + 1] = A[j];  //元素后移}A[j + 1] = temp;}
}
void mergeSort(int A[], int low, int high) {if (low < high) {int mid = (low + high) / 2;mergeSort(A, low, mid);// 归并排序前半段mergeSort(A, mid + 1, high);//归并排序后半段merge(A, low, mid, high);  //将数组A中low到mid和mid+1到high范围内的两段有序序列归并成一段有序序列}
}

天勤数据结构代码——排序相关推荐

  1. 天勤数据结构代码——栈基本操作

    顺序栈 typedef struct SqStack {int data[maxSize]; //存放栈元素,数组大小,要开足够大(一般题目给)不给就开足够大,写注释.int top; //栈顶下标( ...

  2. 天勤数据结构代码——链表基本操作

    结构定义 typedef struct LNode {int data; // 数据域(可以是其他类型)struct LNode *next;//指针域 (此处代表指向后驱节点) }; A和B是两个单 ...

  3. 天勤数据结构-代码题2

    已知一个带有表头节点的单链表,节点结构为:{data,next},假设该链表只给出了头指针head,在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第k个位置上的结点.查找成功返回该结 ...

  4. 【数据结构】排序算法及优化整理

    排序算法 排序算法 选择排序 Selection Sort 插入排序 Insertion Sort 归并算法 Merge Sort 快速排序 Quick Sort 堆排序 Heap Sort 二叉堆的 ...

  5. 鸡尾酒排序算法c语言,[golang] 数据结构-鸡尾酒排序

    吐个槽 又是一个不正经取名的排序算法.真要说和鸡尾酒间的关系,大概就是想喝到鸡尾酒(得到排序好的队列)就要摇晃酒杯让不同的成分混合均匀(向两个方向冒泡排序) 原理 鸡尾酒排序(Cocktail Sor ...

  6. 数据结构------选择排序

    数据结构------选择排序 原理:参考趣学数据结构 代码: #include<stdio.h> #include<stdlib.h> void simpleSelectSor ...

  7. 数据结构-王道-排序

    排序 关于排序算法的视频演示 直接插入排序 从上面的插入排序思想中,不难得到一种简单直接的插入排序算法.假设待排序表在某次过程中属于这种情况. |有序序列\(L[1\ldots i-1]\)|L(i) ...

  8. 希尔排序python 简书_数据结构_排序_直接插入+希尔排序

    数据结构_排序_直接插入排序+希尔排序 其实主要是为了讲述希尔排序,不过插入排序是希尔排序的基础,因此先来讲直接插入排序. 一.直接插入排序 1.原理 下标 0 1 2 3 4 5 6 7 8 -- ...

  9. 【图解数据结构】排序全面总结(一)

    目录 一.前言 学习目标: 二.基本概念 1.排序 2.排序方法的稳定性 3.内部和外部排序 三.插入类排序 1.直接插入排序 2.折半插入排序 3.希尔排序 四.交换类排序 1.冒泡排序 2.快速排 ...

  10. 树的数据结构代码_如何以无代码方式学习树数据结构

    树的数据结构代码 The tree data structure can form some of the most useful and complex data structures in all ...

最新文章

  1. 关于完美拖拽的问题三
  2. static静态关键词 1214
  3. 图解PCB板元器件焊接流程
  4. ansible执行拷贝/脚本/任务计划/yum/service
  5. Linux下C语言实现俄罗斯方块——详细版
  6. 微信支付提示:支付失败,如果已经扣款,资金会在0~3个工作日内原路退回
  7. KB,MB单位转换(Vue)
  8. Spring 整合Hibernate 开发实例
  9. h5实现图片预览效果,模拟淘宝上传图片样式
  10. [需求管理-3]:什么是需求分析?常用的需求分析的流程与方法
  11. 微信小程序使用template标签实现五星评分
  12. win10的开机启动文件夹
  13. 关于UGUI如何自动拓展父物体大小
  14. 奇瑞新能源的小车为何备受市场青睐?鲍思语这样解释
  15. hi3559Av100 行车记录仪系统框图
  16. python实现多重排序(多级排序)
  17. 小萌库 - 精品游戏精彩回顾
  18. 怎么把照片改成jpg格式?照片如何转换jpg格式?
  19. postmarketOS与Ubports星光闪耀
  20. 理解Servlet和Servlet容器、Web容器等概念

热门文章

  1. 局域网 服务器禁止共享文件夹,一键设置局域网共享文件夹权限,禁止他人打印...
  2. 计算机网络第七版1-3
  3. 随机森林原始论文_【论文笔记】韩家炜团队AutoPhrase:从大量文本库中 自动挖掘短语...
  4. XP桌面背景文件路径
  5. 莫烦Tensorflow学习笔记(10-12)——构建简单的神经网络及其可视化
  6. 数据库变为可疑_数据库出现可疑解决办法
  7. 处理器架构 (四) ARM指令集
  8. 如何按页进行PDF文档拆分
  9. 使用Luyten工具反编译jar包
  10. 一款强大的反编译工具luyten