算法和数据结构
你的代码没bug
No Bug
展开
-
C/C++实现堆排序
介绍堆排序是指利用堆这种数据结构所设计的一种排序算法。首先,堆不是容器,而是组织容器元素的一种特别方式。堆的逻辑结构与完全二叉树类似。堆又分为大顶堆和小顶堆大顶堆: 父节点总是大于或等于子节点小顶堆: 父节点总是小于或等于子节点下文利用大顶堆进行堆排序。 代码堆排序,利用大顶堆对数组进行排序,那么我们就得先构造大顶堆。思路: 把所有非终端结点都检查一遍,也就是把所有父结点遍历一遍,看其是否满足大顶堆要求。按照上图,从最后一个父结点开始,是下标 i=(数组长度)/2 的元素,原创 2021-08-12 20:30:09 · 1141 阅读 · 4 评论 -
C/C++实现简单选择排序
介绍从待排序元素中选择最小/最大元素,与待排序元素第一位交换。 实现void SelectSort(int A[],int n){ for(int i=0;i<n-1;i++){ int min=i; for(int j=i+1;j<n;j++){ if(A[j]<A[min])min=j; } if(min!=i)swap(A[i],A[min]); }}代码比较简单:外层for循环,控制运行次数,前面n-1个元素处理好之后,最后一个原创 2021-08-09 14:30:18 · 165 阅读 · 0 评论 -
C/C++实现快速排序(两种方式)
介绍快速排序是对冒泡排序算法的一种改进,快速排序算法通过多次比较和交换来实现排序。流程如下:(图片来自百度) 实现以下有两种实现方式,说是两种,其实就是在交换元素时具体细节上有点不同罢了。方式一int Partition(int A[],int low,int high){ int pivot=A[low];//第一个元素作为基准 while(low<high){ while(low<high && A[high]>=pivot) hig原创 2021-08-09 14:05:15 · 13354 阅读 · 3 评论 -
C/C++实现冒泡排序
介绍冒泡排序是一种交换排序,如果是升序的话,就是把较大值通过交换不断放到后面。 实现下面的代码是将较大值冒泡到数组后面,达到升序的效果;也可以从数组后,通过冒泡,把较小值放到数组前(其实也是较大值放到数组后),达到升序的效果。从前往后:void BubbleSort(int A[],int n){ for(int i=n-1;i>0;i--){ bool flag=false; for(int j=0;j<i;j++){ if(A[j]>A[j+1]原创 2021-08-09 11:02:10 · 634 阅读 · 0 评论 -
C/C++实现希尔排序(两种方式)
介绍希尔排序又称 “缩小增量排序”,它也是一种插入类排序的方法。希尔排序原理:希尔排序属于插入类排序,是 将整个有序序列分割成若干小的子序列 分别进行 插入排序。具体原理可看下图:......原创 2021-08-08 14:51:07 · 7669 阅读 · 1 评论 -
C/C++实现插入排序(三种方式)
介绍插入排序有点像打扑克牌,每次获得一张牌,我们就插入到这个有序序列的合适位置。用数组来看的话就是下面这个样子: 实现(三种方式)方式一经常用到的一种方式//普通的插入排序 void InsertSort1(int A[],int n){ int i,j,temp; for(i=1;i<n;i++){ if(A[i]<A[i-1]){ temp=A[i]; for(j=i-1;j>=0&&A[j]>temp;--j){原创 2021-08-08 10:49:05 · 6867 阅读 · 0 评论 -
C/C++实现图的邻接矩阵
图的存储:邻接矩阵 代码#include <iostream>#include <stdlib.h>#define MaxVertexNum 100using namespace std;typedef char VertexType;typedef int EdgeType;typedef struct{ VertexType Vex[MaxVertexNum];//顶点表 EdgeType Edge[MaxVertexNum][MaxVer原创 2021-07-22 09:38:55 · 1791 阅读 · 0 评论 -
C/C++实现树的双亲表示法(树的顺序存储)
图示存储结构: 代码#include <iostream>#include <stdio.h>#define MAX_TREE_SIZE 100using namespace std;typedef char ElemType;typedef struct{ ElemType data; int parent;}PTNode;typedef struct{ PTNode nodes[20]; int n; }PTree;int原创 2021-07-02 15:22:35 · 847 阅读 · 0 评论 -
C/C++实现二叉树的顺序存储
实现原理要用顺序存储的方式存储二叉树,前提为该二叉树中,结点顺序与完全二叉树结点顺序一致。 代码#include <iostream>#include <math.h>#define MaxSize 100using namespace std;typedef int ElemType;typedef struct TreeNode{ ElemType value; bool isEmpty;//结点是否为空 }TreeNode;int原创 2021-07-02 11:13:47 · 1324 阅读 · 0 评论 -
C/C++实现中序线索二叉树
何为中序线索化线索二叉树可以分为三种:1.将二叉树按照中序遍历构造线索二叉树,则称为中序线索化2.前序线索化3.后序线索化 本文介绍中序线索化中序线索二叉树的结点:初始化时,ltag和rtag都为0,只有结点指向中序前驱或中序后继时,二者的值才会修改为1。 寻找二叉树中序前驱!!!按照链接中方法找中序前驱,只能重头遍历树。如果将二叉树线索化,比如将二叉树进行中序线索化,那么就可以很方便的找到中序前驱。如下图: 代码#include <io原创 2021-06-30 11:11:04 · 1058 阅读 · 0 评论 -
C/C++实现寻找二叉树中序前驱
功能寻找二叉树中序前驱中序前驱: 中序遍历序列的前一个如:该二叉树的中序遍历的结果为DGBEAFC,如果找F结点的前驱,即序列中的A。该方法在构造线索二叉树时起到关键作用!! 代码InOrder函数实际上就是中序遍历,其包含的visit函数作用是寻找前驱:如果q和p指向了同一个结点,那么pre就是前驱;如果不同,则pre按照中序遍历向前移动,然后q按照中序遍历继续向前。#include <iostream>#include <stdlib.h>us原创 2021-06-30 10:30:11 · 1026 阅读 · 1 评论 -
C/C++实现二叉树的前、中、后序遍历(递归与非递归方式)
二叉树的前、中、后序遍历又分为:1.递归遍历2.非递归遍历本文介绍递归遍历。非递归遍历(戳这里!) 基本功能1.利用前序遍历的思想创建二叉树2.前、中、后序遍历利用前序遍历的思想创建二叉树!!! 代码#include <iostream>#include <stdlib.h>using namespace std;typedef char ElemType;typedef struct BiTNode{ ElemType原创 2021-06-28 17:24:18 · 272 阅读 · 0 评论 -
C/C++实现串的模式匹配:暴力匹配算法
时间复杂度假设主串的长为n,模式串(子串)的长为m。最坏时间复杂度为O(nm):最坏情况也就是,每次匹配到模式串的最后一位时,才发现不等,即比较了m次。对于主串,要和模式串配对n-m+1次。时间复杂度即为O(m*(n-m+1))=O(nm-m2+m),一般情况下,n远大于m,即nm远大于m2,最后为O(nm)。最好时间复杂度为O(n):即主串每次与模式串第一位比较时就失败,那么比较1次;共比较n-m+1次。时间复杂度为O(1*(n-m+1)),即O(n)。 代码#include &原创 2021-06-25 20:14:01 · 1168 阅读 · 0 评论 -
C/C++串的定长顺序存储表示
存储原理串有三种存储结构:1.定长顺序存储表示2.堆分配存储表示(即不定长顺序存储表示,因为malloc会在堆区分配空间,所以又称为堆分配存储表示)3.块链存储表示(类似于单链表,一个结点可以存储一个或多个字符,然后指向下一个结点,存储不满的用‘#’填充)本文主要介绍定长顺序存储表示,即用一个一维数组存储字符串。 主要功能1.初始化字符串2.输出字符串3.求字符串的长度4.截取子串5.比较两个字符串6.在主串中定位子串的位置7.连接两个串 代码#in原创 2021-06-25 17:07:16 · 945 阅读 · 0 评论 -
C/C++利用十字链表压缩存储存储稀疏矩阵
利用三元组实现稀疏矩阵的压缩存储代码#include <iostream>#include <stdlib.h>using namespace std;//定义链表中的结点 typedef struct OLNode{ int i,j,e; struct OLNode *right,*down; }OLNode,*OLink;typedef struct{ OLink *rhead,*chead;//行和列链表头指针 int mu,nu,tu; //矩阵原创 2021-06-24 21:09:00 · 812 阅读 · 1 评论 -
C/C++利用三元组实现稀疏矩阵的压缩存储
存储原理对于稀疏矩阵有两种存储方式:三元组和十字链表法。本文介绍用三元组存储。 代码【注】:稀疏矩阵的下标从1开始,而一维数组下标从0开始#include <iostream>using namespace std;//定义结点typedef struct Node{ int i; int j; int data;}Node;int main(){ int n; printf("请输入稀疏矩阵的维数:"); scanf("%d",&n);原创 2021-06-24 19:43:15 · 872 阅读 · 2 评论 -
C/C++实现对三角矩阵的压缩存储
存储原理对三角矩阵:|i-j|<=1的位置上为非零元素,也就是我们要存储的元素;|i-j|>1的位置上全是0,对于0我们不进行压缩存储。原理: 矩阵从下标1开始,对于ai,j,其前i-1行共有3*(i-1)-1个元素(第一行为2个,其余行为3个),该元素在本行的位置为j-i+2。所以该元素在矩阵中的位置为2i+j-2。如果要存入一维数组中,那么还要减一,即在数组中的位置为2i+j-3。 代码#include <iostream>#include<stdl原创 2021-06-24 10:42:09 · 1108 阅读 · 0 评论 -
C/C++实现上、下三角矩阵的压缩存储
存储思路上、下三角的压缩存储和对称矩阵的压缩存储(上三角部分、下三角部分)类似,不过是多了一个常数要存储。对称矩阵的压缩存储 代码#include <iostream>using namespace std;int main(){ int n; printf("请输入下三角矩阵的维数:"); scanf("%d",&n); int arr[n+1][n+1]; printf("请输入下三角矩阵:\n"); for(int i=1;i<n+原创 2021-06-23 17:55:14 · 2658 阅读 · 0 评论 -
C/C++实现对称矩阵的压缩存储
存储原理对于对称矩阵,用一维数组只存储上三角或者下三角。本文只实现了存储下三角,如果只存储上三角,道理是一样的。存储下三角时,又分为按行优先存储和按列优先存储按行优先存储:把下三角一行一行的存储到一维数组中按列优先存储:把下三角一列一列的存储到一维数组中 代码【注】:1.在以下代码中,矩阵下标从1开始,而一维数组下标从0开始。2.对于下三角,第一行1个元素,第二行2个元素以此类推,便可以得到全部要存储的元素,即一维数组大小。3.下三角中,对于当前元素,从矩阵中如何映射到数组中是原创 2021-06-23 16:48:19 · 3447 阅读 · 0 评论 -
C/C++用栈实现中缀表达式的计算
基本思路中缀表达式转后缀表达式实现后缀表达式的计算如果了解中缀转换为后缀的程序,以及了解计算后缀表达式的程序,那么改算法就会很容易,不过是二者的结合,然后代码稍微做一点改变,基本思路不变。1.初始化两个栈:操作数栈和运算符栈2.若扫描到操作数,压入操作数栈3.若扫描到运算符或界限符,按照“中缀转后缀”相同的逻辑压入运算符栈每当弹出一个运算符,就需要弹出两个操作数执行相应的运算 代码代码还是蛮复杂的,建议先搞懂:1.中缀表达式如何转为后缀表达式 2.如何计算后缀表达式 这两个原创 2021-06-22 20:01:15 · 1190 阅读 · 0 评论 -
C/C++用栈实现后缀表达式的计算
基本思路1.从左往右扫描下一个元素,直到处理完所有元素2.若扫描到操作数则压入栈,并回到1;否则执行33.若扫描到运算符,则弹出两个栈顶元素,执行相应的运算,运算结果压回栈顶。回到1. 代码【注】:碰到操作符进行运算时,先弹出的元素为右操作数,后弹出的元素为左操作数。#include <iostream>#include <stack>#include <cstring>using namespace std;bool isNum(c原创 2021-06-22 19:00:59 · 694 阅读 · 0 评论 -
C/C++实现中缀表达式转后缀表达式
基本思路1.遇到数字,直接输出,加入到后缀表达式中2.遇到"(“直接入栈;遇到”)"依次弹出栈内运算符直到“(”。但是“(”不输出。3.遇到运算符。依次弹出栈中优先级高于或等于当前运算符的所有运算符,加入后缀表达式中。碰到“(”或栈空则停止。再把当前运算符加入栈中。4.最后输出栈中所有剩余运算符。 代码#include <iostream>#include <stdlib.h>#include <stack>#include <cstr原创 2021-06-22 11:35:17 · 909 阅读 · 0 评论 -
C/C++实现栈在括号匹配中的应用
基本思路1.碰到左括号,则入栈2.碰到右括号,如果栈不为空,则弹出栈顶元素,进行匹配。匹配成功则继续,匹配失败直接结束。3.最后栈为空,则表示成功代码代码前半部分是实现栈的基本操作,如果会c++中自带的栈,那么将会简化许多。代码核心功能是bracketCheck()。#include <iostream>#include <stdlib.h>#define MaxSize 10using namespace std;typedef char ElemType;原创 2021-06-21 21:17:36 · 386 阅读 · 0 评论 -
C/C++实现链式队列
基本功能1.初始化链式队列:带头结点2.入队3.出队4.输出队列 代码链式队列用单链表来实现,所以掌握了单链表就掌握了链式队列。不同的是,在定义结点、定义队列时和单链表有点区别。链式队列比单链表多了两个指针,分别指向队头和队尾结点,所以定义队列时,不仅定义结点,还要定义这两个指针。#include <iostream>#include <stdlib.h>using namespace std;typedef int ElemType;/原创 2021-06-21 08:53:38 · 396 阅读 · 0 评论 -
C/C++实现循环队列
基本功能初始化循环队列入队出队获得队头元素输出队列 代码【注】:一、Q.rear指向最后一个元素的下一个位置二、判空操作为Q.front == Q.rear,如果把循环队列填充满,那么判满操作也为上述语句,这样就会分不清队列是空还是满。有以下三种方法来解决:1.空出一个位置不放元素,那么判满语句为(Q.rear+1)%MaxSize==Q.rear2.在结构体内设置size属性,表示队列当前大小。这样就不用空出一个位置,判满语句为Q.rear ==Q.front&原创 2021-06-21 08:13:42 · 501 阅读 · 0 评论 -
C/C++实现共享栈
何为共享栈两个栈共享一个存储空间。两个栈的指针分别为top1和top2。 基本功能1.初始化共享栈2.判断共享栈是否为空3.栈1和栈2:进栈、出栈4.获得栈1和栈2的栈顶元素 代码#include <iostream>#include <stdlib.h>#define MaxSize 10using namespace std;typedef int ElemType;typedef struct{ ElemType原创 2021-06-19 17:18:21 · 742 阅读 · 0 评论 -
C/C++实现顺序栈
基本功能初始化栈判栈空进栈出栈读取栈 代码#include <iostream>#include <stdlib.h>#define MaxSize 10using namespace std;typedef int ElemType;typedef struct{ ElemType data[MaxSize]; int top;}SqStack;void InitStack(SqStack &S);//初始化栈 b原创 2021-06-19 15:53:22 · 140 阅读 · 0 评论 -
C/C++实现循环单链表:带头结点
基本功能初始化循环单链表:带头结点建立循环单链表:头插法、尾插法按位查找元素按值查找元素按位序插入元素按位序删除元素输出循环单链表 代码循环单链表和循环双向链表有很多相似之处,可以对比学习。#include <iostream>#include <stdlib.h>using namespace std;typedef int ElemType;typedef struct LNode{ ElemType data; struct原创 2021-06-19 09:02:36 · 300 阅读 · 0 评论 -
C/C++实现双向循环链表:带头结点
基本功能初始化双向循环链表:带头结点创建双向循环链表:头插法、尾插法正向、逆向遍历双向循环链表按位序查找元素按值查找元素按位序插入元素按位序删除元素代码#include <iostream>#include <stdlib.h> using namespace std;typedef int ElemType;typedef struct DNode{ ElemType data; struct DNode *prior,*next;}DNo原创 2021-06-19 07:41:48 · 312 阅读 · 0 评论 -
C/C++实现双向链表:带头结点
基本功能1.初始化双向链表:带头结点2.创建双链表:头插法3.创建双向链表:尾插法4.正向遍历链表5.逆向遍历链表6.按位序查找元素7.按值查找元素8.按位序插入9.按位序删除 代码#include <iostream>#include <stdlib.h>using namespace std;typedef int ElemType;typedef struct DNode{ ElemType data; struct DN原创 2021-06-18 07:46:17 · 503 阅读 · 3 评论 -
C++实现单链表:不带头结点
C++实现单链表:带头结点基本功能初始化单链表建立单链表:头插法和尾插法遍历单链表按位序查找元素按值查找元素按位序插入结点按位序删除结点求单链表长度 代码相比较带头结点的单链表,不带头结点的单链表实现部分函数时,要单独考虑第一个结点。而带头结点的单链表则不需要单独考虑。#include <iostream>#include <stdlib.h>using namespace std;typedef int ElemType;//定原创 2021-06-17 16:19:44 · 2330 阅读 · 3 评论 -
C++实现单链表:带头结点
基本功能初始化单链表建立单链表:头插法和尾插法遍历单链表按位序查找元素按值查找元素按位序插入结点按位序删除结点求单链表长度 代码#include <iostream>#include <stdlib.h>using namespace std;typedef int ElemType;//定义单链表结点 typedef struct LNode{ ElemType data; struct LNode *next;}LNode原创 2021-06-17 11:33:03 · 332 阅读 · 0 评论 -
C++实现静态顺序表与动态顺序表
基本功能静态顺序表用数组实现,需要注意的是,顺序表的第一个元素在数组的第0位。1.初始化顺序表2.插入元素(越界处理)3.按位查找4.按值查找5.输出顺序表6.删除元素其实无论是C还是C++实现,二者都相似,只是函数传参时不太一样。C++使用“&”,在C中采用指针也可以达到同样的效果。 代码基本功能已实现,考虑到了插入删除越界问题!#include <iostream>#include <stdio.h>#define MaxSize原创 2021-06-16 11:10:22 · 259 阅读 · 0 评论 -
斐波那契数列递归与非递归时间复杂度
问题来自王道考研数据结构书籍,思维拓展斐波那契数列有两种常用的算法:递归算法和非递归算法。试分别分析两种算法的时间复杂度。 递归方式递归方式代码:递归结束条件可以不同,如果数列从第一个开始且为1,那么就是如下结束条件。如果从第0个开始且第0个为0,那么结束条件就会改变:n等于0时返回0,n等于1时返回1#include <stdio.h>#include <stdlib.h>int Fibonacci(int n){ if(n==1||n==2)原创 2021-06-15 16:05:41 · 8262 阅读 · 2 评论 -
C++中vector的基本方法
本文简单的总结了vector的方法,并未提供详细使用,供读者忘记方法时使用。使用vector时,要导入include< vector > 头文件。1.push_back 将数据放入vector中2.pop_back 去掉末尾元素3.at 得到对应下标的元素4.begin 得到数组头的指针5.end ......原创 2020-03-29 15:58:30 · 2326 阅读 · 0 评论 -
C++中栈和队列的基本方法
栈栈的方法1.push()将元素入栈2.pop()删除栈顶元素,不会返回3.top()返回栈顶元素,但不删除4.size()栈的大小5.empty() 判断栈是否为空队列队列的方法1.push()将元素放入队列2.pop()删除队首元素3.front()返回队首元素,但不删除4.back()返回队尾元素,但不删除5.size()队列的大小6.empty() 判断队...原创 2020-03-27 15:24:57 · 446 阅读 · 0 评论 -
vector中erase方法详解
方法参数有一参函数和双参函数1.iterator erase(iterator position);2.iterator erase(iterator first, iterator last);iterator erase(iterator position);①删除指针所指的元素②返回指向下一个元素的迭代器iterator erase(iterator first, iterator last);①删除[first,last)范围内的元素,不包含last②返回指向last元素的迭代器(原创 2020-09-27 21:20:14 · 5177 阅读 · 0 评论 -
C++自定义函数排序
sort的自定义函数排序sort函数有三个参数:第一个参数为起始地址第二个参数为结束地址第三个参数为排序方式第三个参数可以不写,如果第三个参数不写,那么就是默认排序方式:从小到大sort利用自定义比较函数:bool cmp(int i1,int i2){ return i1<i2;}sort(arr,arr+n,cmp); 结构体内置自定义函数排序基本语法:typedef struct time{ int c; bool operator < (con原创 2020-09-26 21:23:47 · 840 阅读 · 0 评论 -
vector<pair<int,int>>的使用及注意点(方法报错)
vector<pair<int,int>>用法vector的这种用法有点类似于map。与map不同的是:map会对插入的元素按键自动排序,而且不允许键重复。vector的这种用法不会自动排序,而且允许重复。map的基本用法:map的基本用法!! 注意点在使用vector<pair<int,int>>时,可能会报以下错误:没有对应方法解决办法:版本:Dev-C++ 4.8.1及以上找到:工具- >编译选项- >程序原创 2020-07-15 16:06:50 · 29352 阅读 · 3 评论 -
C++中的set常用方法(multiset、unordered_set)
set的特点set和map一样,它们的实现原理都是红黑树。set 在插入元素时,通过比较元素的大小,实现二叉树自平衡。需要注意的是,set不允许插入相同的元素。或者说,set可以让你插入重复的元素,不会报错,但是set容器中就一个。这就是set的一个重要功能:去重。 当数组转换为set时,不仅给你排好了序,而且连重复的元素都没有了。但是我们有时候确实想用set,而且还想有重复的元素,那么 multiset 就派上了用场!(后文有提及) set常用方法简单总结一下set的常用方法。原创 2020-07-08 17:53:47 · 1405 阅读 · 0 评论