算法与数据结构

数据结构与算法之排序算法

橙三吉。 提交于 2020-01-21 15:03:38
排序 内部排序 插入排序 直接插入排序 希尔排序 选择排序 简单选择排序 堆排序 交换排序 冒泡排序 快速排序 归并排序 基数排序 外部排序 内部排序 插入排序 直接插入排序 是对于欲排序的元素以插入的方式找寻元素的适当位置,以达到排序的目的 思路: 插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。 如上图,我们所说的有序表是前面有括号包着的表,后面是无序表。我们每一次都把无序表的第一个元素插入到有序表中,并与有序表的最后一个元素比较,如果比它大就查到后面去,如果比它小,就一个一个往前比较,直到找到位置位置。 代码实现 // 插入排序 public static void insertSort ( int [ ] arr ) { // 使用逐步推导的方式来讲解,便于理解 // 从最后一个开始 遍历到最后一个 for ( int i = 1 ; i < arr . length ; i ++ ) { // 定义待插入的数 int insertVal = arr [ i ] ; int insertIndex = i - 1 ; /

数据结构与算法——复杂度分析

可紊 提交于 2020-01-21 05:18:06
1、大O复杂度表示法 1.1、从维度划分 从维度划分可分为:时间复杂度、空间复杂度 1.1.1、时间复杂度 概念 代码执行时间随数据规模增长的变化趋势 多项式量级复杂度分析规则(非多项式量级不常见暂不考虑) 顺序相加,嵌套相乘,取最高阶 阶数排序 幂阶( n 4 > n 3 > n 2 n^4>n^3>n^2 n 4 > n 3 > n 2 )>线性对数阶( n l o g n nlogn n l o g n )>线性阶( n n n )>对数阶( l o g n logn l o g n )>常数阶(1) 举例 int a = 0 ; for ( int i = 0 ; i < n ; i ++ ) { a = a + 1 ; for ( int j = 0 ; j < n ; j ++ ) { a = a + 2 ; } } int b = 1 ; while ( b <= n ) { b = b * 10 ; } 第一行:执行1次 第二行:循环执行n次 第三行:循环执行n次 第四行:循环执行 n 2 n^2 n 2 次 第五行:循环执行 n 2 n^2 n 2 次 第八行:循环执行 l o g n logn l o g n 次 总计: 2 n 2 + 2 n + l o g n + 1 2n^2+2n+logn+1 2 n 2 + 2 n + l o g n + 1 次

数据结构--广义表

心不动则不痛 提交于 2020-01-21 04:16:24
广义表的定义 带表名的广义表表示 广义表的特性 线性结构 多层次结构,有深度 可共享 可递归 广义表抽象数据类型 package pers . zhang . genList ; /** * @author zhang * @date 2020/1/20 - 10:57 * * 广义表抽象数据结构 */ public interface GGenList < T > { //判断广义表是否为空 boolean isEmpty ( ) ; //返回广义表长度 int length ( ) ; //返回广义表的深度 int depth ( ) ; //插入原子x作为第i个元素 GenListNode < T > insert ( int i , T x ) ; //插入子表作为第i个元素 GenListNode < T > insert ( int i , GenList < T > glist ) ; } 广义表的存储结构 广义表的单链表示: 广义表的双链表示: 广义表双链表示的实现 广义表双链表示的节点类: package pers . zhang . genList ; /** * @author zhang * @date 2020/1/20 - 11:03 * * 广义表双链表示的节点类 */ public class GenListNode < T > { //数据域

【数据结构】时间复杂度的计算

与世无争的帅哥 提交于 2020-01-20 22:09:54
作者:raymondCaptain 链接:https://www.jianshu.com/p/f4cca5ce055a 来源:简书 我们假设计算机运行一行基础代码需要执行一次运算。 int aFunc ( void ) { printf ( "Hello, World!\n" ) ; // 需要执行 1 次 return 0 ; // 需要执行 1 次 } 那么上面这个方法需要执行 2 次运算 int aFunc ( int n ) { for ( int i = 0 ; i < n ; i ++ ) { // 需要执行 (n + 1) 次 printf ( "Hello, World!\n" ) ; // 需要执行 n 次 } return 0 ; // 需要执行 1 次 } 这个方法需要 (n + 1 + n + 1) = 2n + 2 次运算。 我们把 算法需要执行的运算次数 用 输入大小n 的函数 表示,即 T(n) 。 此时为了 估算算法需要的运行时间 和 简化算法分析,我们引入时间复杂度的概念。 定义:存在常数 c 和函数 f(N),使得当 N >= c 时 T(N) <= f(N),表示为 T(n) = O(f(n)) 。 如图: 当 N >= 2 的时候,f(n) = n^2 总是大于 T(n) = n + 2 的,于是我们说 f(n) 的增长速度是大于或者等于 T

数据结构与算法(C++)--链表

大憨熊 提交于 2020-01-20 11:22:20
线性表的链性存储结构 线性表中的数据元素(结点)在存储器的位置是任意的,即逻辑上相邻的数据元素在物理位置上不一定相邻 结点 链表 n个结点由指针链组成一个 链表 单链表的基本操作 单链表的初始化 构造一个空表 步骤: 生成新结点作为头结点,用头指针L去指向头结点 将头结点的指针域置空 Status InitList_L ( LinkList & L ) { L = new LNode ; L - > next = NULL ; return OK ; } 补充: 判断链表是否为空 int ListEmpty ( LinkList L ) { > if ( L - > next ) //非空 > return 0 ; > else > return 1 ; > } 补充: 单链表的销毁 首先让 P =L 然后将L的下一个地址赋值给L,L = L->next 然后就可以放心删除(释放)前一个数据了,delete P 就这样依次释放所有结点,直到 L==NULL Status DestroyList_L ( LinkList & L ) { Lnode * p while ( L ) { p = L ; L = L - > next ; delete P ; } } 补充: 清空链表,链表依然存在,只是没有元素了。只剩下头指针和头结点 首先将首元结点赋值给p,p= L->next

数据结构与算法(栈和队列)

Deadly 提交于 2020-01-20 05:04:35
首语 历经一个月的时间,自己终于搭建完成了个人网站,还在持续优化中,网站采用halo博客系统,功能非常强大!欢迎大家来我的网站逛逛。有什么建议可以留言! 网站地址: http://www.yanghujun.com 接下来我们开始第二节的数据结构学习,栈和队列。 栈 栈是限定仅在表尾进行插入和删除操作的线性表。 允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈称为空栈。栈又称为后进先出 的线性表。 栈的顺序存储结构 如用数组实现,栈底是:下标为0的一端。 栈的链式存储结构 链栈的出入栈操作 链栈的入栈操作 s - > data = e ; s - > next = stack - > top ; stack - > top = s ; stack - > count ++ ; 链栈的出栈操作 p = stack - > top stack - > top = p - > next ; free ( p ) stack - > count -- ; 栈的经典实用(逆波兰表达式法) 标准四则运算表达式——中缀表达式 9+(3-1)*3+10/2 计算机采用——后缀表达式 9 3 1 - 3 * + 10 2 / + 中缀表达式转后缀表达式 数字输出,运算符进栈,括号匹配出栈,栈顶优先级低出栈。 代码实现 中缀表达式->后缀表达式 /** *

数据结构与算法

点点圈 提交于 2020-01-20 04:53:34
1. 时间复杂度计算 基本操作,即只有常数项,认为其时间复杂度为O(1) 顺序结构,时间复杂度按加法进行计算 循环结构,时间复杂度按乘法进行计算 分支结构,时间复杂度取最大值 判断一个算法的效率时,只需关注操作数量的最高次项,其他次要项和常数项可以忽略 常见时间复杂度大小判断 O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)< O(n!) < O(n^n) 2.顺序表 定义 :将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。 2.1顺序表的两种基本实现方式 max :元素存储区的容量 num :元素存储区的当前已有元素个数 2.2元素存储区替换 一体式结构需要整体搬迁,而分离式结构只需将表信息区中的数据链接地址更新,而该顺序表对象不变。 2.3增加元素、删除元素 3.链表 链表 :是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。 3.1 单向链表 是链表中最简单的一种形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。 3.2 双向链表 每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值

【数据结构】选择、插入、归并、快排、堆排序总结

a 夏天 提交于 2020-01-20 04:32:01
选择排序: 下面这个选择排序的思路: 找出所有元素中最小的元素 ,然后依次按 从小到大 放进数组中 # include <iostream> # include <algorithm> using namespace std; void selectionSort(int arr[], int n){ for(int i = 0 ; i < n ; i ++){ // 寻找[i, n)区间里的最小值 int minIndex = i; for( int j = i + 1 ; j < n ; j ++ ) if( arr[j] < arr[minIndex] ) minIndex = j; //找到最小的元素的位置 swap( arr[i] , arr[minIndex] ); //和当前的数组的位置进行交换 } int main() { int a[10] = {10,9,8,7,6,5,4,3,2,1}; selectionSort(a,10); for( int i = 0 ; i < 10 ; i ++ ) cout<<a[i]<<" "; cout<<endl; return 0; } //此处用到了模板类,可以方便测试的时候进行任何数值去测试 template<typename T> void selectionSort(T arr[], int n){ for(int

数据结构与算法题目集(中文)6-5 链式表操作集 (20分)

末鹿安然 提交于 2020-01-20 04:12:16
本题要求实现链式表的操作集。 函数接口定义: Position Find( List L, ElementType X ); List Insert( List L, ElementType X, Position P ); List Delete( List L, Position P ); 其中 List 结构定义如下: typedef struct LNode *PtrToLNode; struct LNode { ElementType Data; PtrToLNode Next; }; typedef PtrToLNode Position; typedef PtrToLNode List; 各个操作函数的定义为: Position Find( List L, ElementType X ) :返回线性表中首次出现X的位置。若找不到则返回ERROR; List Insert( List L, ElementType X, Position P ) :将X插入在位置P指向的结点之前,返回链表的表头。如果参数P指向非法位置,则打印“Wrong Position for Insertion”,返回ERROR; List Delete( List L, Position P ) :将位置P的元素删除并返回链表的表头。若参数P指向非法位置,则打印“Wrong Position

数据结构—算法时间复杂度、空间复杂度和问题规模

我怕爱的太早我们不能终老 提交于 2020-01-20 02:11:57
1、时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出来的,必须上机运行测试才能知道。但我们不可能也没有必要对每个算法都上机测试,只需知道哪个算法花费的时间多,哪个算法花费的时间少就可以了。并且一个算法花费的时间与算法中语句的执行次数成正比例,哪个算法中语句执行次数多,它花费时间就多。一个算法中的语句执行次数称为语句频度或时间频度。记为T(n)。 (2)时间复杂度 在刚才提到的时间频度中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律。为此,我们引入时间复杂度概念。 一般情况下, 算法中基本操作重复执行的次数是问题规模n的某个函数,用T(n)表示 ,若有某个辅助函数f(n),使得当n趋近于无穷大时, T(n)/f(n) 的极限值为不等于零的常数,则称f(n)是T(n)的同数量级函数。记作 T(n)=O(f(n)), 称 O(f(n)) 为算法的渐进时间复杂度,简称时间复杂度。 另外,上面公式中用到的 Landau符号其实是由德国数论学家保罗·巴赫曼(Paul Bachmann)在其1892年的著作《解析数论》首先引入,由另一位德国数论学家艾德蒙·朗道(Edmund Landau)推广。 Landau符号的作用在于用简单的函数来描述复杂函数行为,给出一个上或下(确)界 。在计算算法复杂度时一般只用到大 O