Permutation(排列组合)

排列问题:

设R = {r1, r2, ... , rn}是要进行排列的n个元素, Ri = R-{ri}; 集合X中元素的全排列记为Permutation(X), (ri)Permutation(X)表示在全排列Permutation(X)的每一个排列前加上前缀ri得到的排列.

R的全排列可归纳定义如下:

当n=1时,Permutation(R)={r},r是集合R中唯一的元素;

当n>1时,Permutation(R)由(r1)Permutation(R1),(r2)Permutation(R2), ..., (rn)Permutation(Rn)构成。

依次递归定义,则可设计产生Permutation(X)的递归算法如下:

template <typename Type>
void permutation(Type *array, int front, int last)
{//已经递归到了最后一个元素if (front == last){//打印输出for (int i = 0; i < front; ++i){cout << array[i] << ' ';}cout << array[front] << endl;return ;}else{for (int i = front; i <= last; ++i){// 不断的从下标为[front ~ last]的元素中选择一个元素//作为当前序列的开头元素std::swap(array[front], array[i]);permutation(array, front+1, last);std::swap(array[front], array[i]);}}
}

算法说明:

算法Permutation(array, k, m)递归地产生所有前缀是array[0:k-1],且后缀是array[k:m]的全排列的所有排列.函数调用(list, 0, n-1)则产生list[0:n-1]的全排列.

算法演示:

char str[] = “abc”;的递归调用过程如图:

小结:

虽然我们自己实现了Permutation, 但C++ STL中也实现了std::next_permutation算法, 在一般应用中, 我比较推荐使用STL中已经实现好的next_permutation, 毕竟STL的代码质量还是非常高的, 而且速度一点也不逊色于我们的实现;

插入排序

插入排序是低级排序中速度最快的一种(冒泡/选择/插入排序效率均为O(N^2)),但是跟快速排序(NlogN),归并排序(NlogN)还是有一定的差距的⊙﹏⊙b汗!

算法思想:

不断的从尚未排序的序列中选择一个元素插入到已经排好序的序列中(当然,会有一个选择插入位置的过程:选择一个位置, 该位置前的元素都比该元素小, 该位置后的元素都比该元素大),类似于现实生活中的斗地主的摸排过程.

//实现与解析
/**说明:outer:第一个未排序的元素inner:搜索第一个小于tmp的元素的位置tmp:  用于暂存第一个尚未排序的元素
*/
template <typename Type>
void insertionSort(Type *begin, Type *end) throw (std::range_error)
{if ((begin == end) || (begin == NULL) || (end == NULL))throw std::range_error("pointer unavailable");//假设第一个元素已经排好序了for (Type *outer = begin+1; outer < end; ++outer){Type tmp = *outer;   //暂存第一个未排序的元素Type *inner = outer;//inner 不断寻找一个位置(*(inner-1) <= tmp),//使得tmp->*inner(tmp所保存的值插入到inner位置)while (inner > begin && *(inner-1) > tmp){*inner = *(inner-1);    //元素后移-- inner;               //指针前移}*inner = tmp;               //将元素插入已排序序列}
}template <typename Iter>
void insertionSort(Iter begin, Iter end)
{return insertionSort(&(*begin), &(*end));
}
/**insertionSort_2算法的由来:可以使用*begin(序列的第一个元素)作为哨兵,这样就可以省去insertionSort 中第15行的inner > begin判断,但付出的代价是begin所指向的位置不能再存储有用的数据,只能被用作排序的哨兵 -> 以空间换时间(个人感觉没什么必要...)
*/
template <typename Type>
void insertionSort_2(Type *begin, Type *end) throw (std::range_error)
{if ((begin == end) || (begin == NULL) || (end == NULL))throw std::range_error("pointer unavailable");for (Type *outer = begin+2; outer < end; ++outer){*begin = *outer;Type *inner = outer;//因为*begin不可能 > *begin, 所以该循环一定会退出while (*(inner-1) > *begin){*(inner) = *(inner-1);--inner;}*inner = *begin;}
}

附-permutation与std::next_permutation测试代码

int main()
{vector<char> str;for (char ch = 'a'; ch <= 'c'; ++ch)str.push_back(ch);permutation(&(*str.begin()), 0, 2);cout << "----------" << endl;typedef vector<char>::iterator Iter_type;do{for (Iter_type iter = str.begin(); iter != str.end(); ++iter)cout << *iter << ' ';cout << endl;}while (std::next_permutation(str.begin(), str.end()));return 0;
}

数据结构基础(3) --Permutation 插入排序相关推荐

  1. 利用for循环调用插入方法批量插入 一条失败_算法与数据结构(1):基础部分——以插入排序为例...

    本文将会以插入排序为例,介绍算法与数据结构的基础部分. 插入排序 排序可以说是整个算法中最为基础,最为重要的一部分,而插入排序正是排序算法中最简单的一种解决办法. 什么是排序问题? 输入:n个数的一个 ...

  2. asp子窗口读取父窗口数据_算法与数据结构基础 - 数组(Array)

    数组基础 数组是最基础的数据结构,特点是O(1)时间读取任意下标元素,经常应用于排序(Sort).双指针(Two Pointers).二分查找(Binary Search).动态规划(DP)等算法.顺 ...

  3. “数据结构基础”系列网络课程主页

    #前言 自从下决心要解决学生动手能力差的问题,开始了课程实践资源的建设之旅:自迷上了翻转课堂,所教课程的视频,也就逐渐形成了体系.在为我自己的校内学生服务的同时,也希望能够让更多人有机会用到. 自全身 ...

  4. 一周刷爆LeetCode,算法da神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记

    一周刷爆LeetCode,算法大神左神(左程云)耗时100天打造算法与数据结构基础到高级全家桶教程,直击BTAJ等一线大厂必问算法面试题真题详解 笔记 教程与代码地址 P1 出圈了!讲课之外我们来聊聊 ...

  5. 数据结构基础知识点,看完保证期末不挂科!

    数据结构基础知识 线性结构 (1)连续储存(地址在内存中为连续)-----数组 (2)离散储存(地址在内存中不一定为连续的)-----链表 非线性结构 (1)树 (2)图 基础算法(查找排序): 折半 ...

  6. 数据结构基础知识核心归纳(一)

    数据结构基础知识核心归纳(一) 转载请声明出处:http://blog.csdn.net/andrexpert/article/details/77900395 Android             ...

  7. 求单链表的最大值与原地逆转_数据结构基础复习09.ppt

    数据结构基础复习09.ppt 数据结构考研辅导 基础复习 浙江大学计算机学院 内容提纲 考研概述 考察目标理解数据结构的基本概念 掌握数据结构的逻辑结构 存储结构及其差异 以及各种基本操作的实现 在掌 ...

  8. 【数据结构基础】之数组介绍,生动形象,通俗易懂,算法入门必看

    前言 本文为数据结构基础数组相关知识,下边将对数组的定义.性质及结构,数组的各种玩法如循环遍历数组.查找数组最大值.数组元素的位移等,二维数组的定义及用法等进行详尽介绍~ Java全栈学习路线可参考: ...

  9. 考研数据结构の基础概念

    考研数据结构の基础概念 第一章 绪论 第二章 线性表 第三章 栈与队列 第四章 串 第五章 矩阵与广义表 第六章 树 第七章 图 第八章 排序 第九章 查找 第一章 绪论 1.数据:是对客观事物的符号 ...

最新文章

  1. 修改 SQL Server 服务器的 IP 地址
  2. python 读excel中的sheet_Python使用一些背景颜色读取Excel工作表(xlsx)中的单元格?...
  3. python 计算数字 k 在 0 到 n 中的出现的次数,k 可能是 0~9 的一个值
  4. HDU 5238 Calculator 线段树 中国剩余定理
  5. 360极速浏览器使用postman
  6. 中班机器人上课视频_家委会:出班费买智能扫地机器人,不用家长搞卫生了,莫名其妙...
  7. 亿万富翁夏令营:库克、巴菲特等出席太阳谷峰会
  8. 安卓APK文件结构解析 怎样去除内置广告 及修改图标和文字
  9. 路由交换技术实战七 FR 网络中配置 OSPF( 完成版 )
  10. 移动网页布局基础:京东网页
  11. 经济数据预测 | Python实现ARIMA时间序列金融市场预测
  12. HDU 5761 Rower Bo(积分)
  13. 关于脚本录制和回放终端会话(script、scriptreplay)使用
  14. 2018-ACM省赛
  15. 【Linux常用指令2】
  16. 2019年全国大学生电子设计大学(D 题)简易电路特性测试仪(2)基础部分电路与代码
  17. java实现编译器_实现一个简单的编译器
  18. soul网关-2-divide插件
  19. Windows Server 2008 安装SVN
  20. 【2018】—不忘初心,砥砺前行

热门文章

  1. # android开发:4-1、Activity启动方式、生命周期、不同activity的数据传递
  2. 编译原理中LL(1)分析程序的设计---用c++程序语言实现
  3. seclists各种字典工具
  4. Springboot之actuator配置不当漏洞(autoconfig、configprops、beans、dump、env、health、info、mappings、metrics、trace)
  5. Python获取同目录下json文件内容
  6. Z-Stack通过按键中断实现长按功能
  7. 关于ZooKeeper的两点思考
  8. 基于vue框架项目开发过程中遇到的问题总结(三)
  9. UWP Acrylic Material
  10. Git HEAD detached from XXX (git HEAD 游离) 解决办法