![](https://img-blog.csdnimg.cn/20201014180756930.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
姜蒋酱7
这个作者很懒,什么都没留下…
展开
-
数据结构 基础总结归纳
满二叉树:在一棵二叉树中,如果所有分支节点都有左右子树 而且所有叶子都在同一层上 这样的二叉树就是满二叉树完全二叉树:对于一颗有n个几点的二叉树按层次编号 如果编号为i的节点与同样深度的满二叉树中编号也为i的节点在二叉树中位置完全相同,那这棵二叉树就是完全二叉树(满二叉树一定是完二叉树 完全二叉树不一定是满二叉树)完全二叉树特点:叶子节点只能出现在最下两层最下层叶子节点一定集中在左边连续的位置(层序编号)同样节点数的二叉树,完全二叉树的深度最小前序遍历:二叉树为空 则返回空 否则先访问根节点原创 2020-12-12 14:41:57 · 132 阅读 · 0 评论 -
宽度优先遍历(BFS)深度优先遍历(DFS)
BFS:set+queueDFS:stack+set以当前结点距离最近的原则输出,使用set记录,避免重复输出,使用queue进行输出void BFS(Node* node){ if (node == NULL)return; unordered_set<Node*>s; queue<Node*>q; q.push(node); s.insert(node); while (!q.empty()) { Node* tmp = q.front(); cou原创 2020-06-17 16:17:26 · 217 阅读 · 0 评论 -
拓扑排序
拓扑排序适用于无环图,且图是有向的,而且要有入度为0的结点分析:使用map存储结点和结点的入度信息,使用队列存储入度为0的信息,依次弹出队列中入度为0的结点,并把与之相连的结点入度减1,如果为零就加入到队列中,最后用一个链表记录输出顺序//拓扑排序list<Node*> Sort(Graph graph){ unordered_map<Node*,int>m; queue<Node*>q; unordered_map<int,Node*>::it原创 2020-06-17 15:36:40 · 136 阅读 · 0 评论 -
图的建立
图的组成元素:顶点边建立顶点类,成员包包括:入度,出度,数值,以此顶点为出发点的边(放入链表中) 当前结点直接相连的下一个结点(放入链表中)class Node{public: int val; int in; int out; list<Node*>next; list<Edge*>edges; Node(int x) :val(x),in(0),out(0){}};边类的构成:边的权值 出发顶点 末尾结点class Edge{publ原创 2020-06-17 15:00:31 · 139 阅读 · 0 评论 -
左神算法课——并查集c++实现
class UnionFindSet{private: hash_map<char, char>fatnerMap; hash_map<char, int>sizeMap;public: UnionFindSet(vector<char>data); char findHead(char cur);//找代表结点 bool isSame(char a, char b);//是否同集合 void Union(char a, char b);//合并};原创 2020-06-16 17:24:36 · 175 阅读 · 0 评论 -
岛问题
1.题目:岛问题一个矩阵中只有0和1两种值,每个位置都可以和自己的上、下、左、右四个位置相连,如果有一片1连在一起,这个部分叫做一个岛,求一个矩阵中有多少个岛?举例:0 0 1 0 1 01 1 1 0 1 01 0 0 1 0 00 0 0 0 0 0这个矩阵中有三个岛。思路:建立一个感染函数,先遍历矩阵,如果发现有为一的地方则调用感染函数,递归进行上下左右的搜索,并把周围为相连为1的地方标记为2,知道搜索到不为1或者越界不在进行递归。#define width 6#define h原创 2020-06-16 16:50:51 · 134 阅读 · 0 评论 -
C++设计RandomPool结构
思想:使用两个map。一个存放string int另一个存放映射 int string 用此来保证等概率删除的时候:用最后的位置来填补删除位之的空缺class Poll{public: Poll() { this->size = 0; } void Map_insert(string); void Map_delete(string); void GetRandom();private: map<string,int>m1; map<int,string&原创 2020-06-11 18:35:13 · 95 阅读 · 0 评论 -
已知一棵完全二叉树,求其节点的个数。要求:时间复杂度低于O(N),N为这棵树的节点个数
///已知一棵完全二叉树,求其节点的个数//给根据二叉树的性质,二叉树的结点个数=2^k - 1;k为二叉树的高度//遍历当前结点左子树最深处,就是二叉树高度(因为完全二叉树是从左边开始堆砌的)//再遍历当前结点右子树的左子树最深处,判断是否到达了k//如果达到了k,那么右子树也是满二叉树,递归右子树//如果未达到k。那么右子树是高度小于左子树的满二叉树,直接公式class TreeNode{public: int val; TreeNode*left; TreeNode* righ原创 2020-06-11 16:19:35 · 364 阅读 · 0 评论 -
判断一个树是否为二叉搜索树
判断一个树是否为二叉搜索树二叉搜索树:任何一个结点都比他的左孩子大,比他的右孩子小思路:中序遍历的顺序是左根右如果中序遍历的数值顺序是升序排列的,那就是二叉搜索树 typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left = NULL; } }*Tree;void Mid(Tree h原创 2020-06-11 15:12:30 · 193 阅读 · 0 评论 -
判断一个树是否为完全二叉树
/判断一个树是否为完全二叉树//思路:当一个只要有一个结点只有右孩子,没有左孩子,直接返回false;//当一个结点不是左右孩子都全的时候://左右都全//有左没右或者左右都没有:当是这种情况的时候,遍历剩下的结点都要是叶节点 typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left =原创 2020-06-11 15:06:31 · 144 阅读 · 0 评论 -
判断一个二叉树是否平衡
//判断是否为平衡二叉树//思路:设计一个返回类,包括了树的高度,是否平衡//递归的去检查左子树,和右子树返回树高度,平衡否?//最后再检查左右子树的高度差//如果大于1,则不平衡,否则选择左右子树较大一个再+1(自己)返回class TreeNode{public: int val; TreeNode*left; TreeNode* right; TreeNode(int x) { this->val = val; this->left = NULL; th原创 2020-06-11 09:54:46 · 103 阅读 · 0 评论 -
二叉树的序列化与反序列化
//二叉树的先序序列化,与反序列化class TreeNode { public: int val; TreeNode *parent; TreeNode*left; TreeNode* right; TreeNode(int x) { this->val = x; this->parent = NULL; this->left = NULL; this->right = NULL; } };typedef class TreeNode *Tree原创 2020-06-11 09:29:19 · 178 阅读 · 0 评论 -
在二叉树中找到一个节点的后继节点、前驱节点
//二叉树找前驱结点:中序遍历中一个结点的上一个,后继结点:中序遍历中一个节点的下一结点//不需要遍历整棵树//方法://1.如果一个结点存在右子树,那么他的后继结点一定是右子树中最左的结点//2.如果没有右子树对于一个节点如果不存在右子树,那么如果当前节点的父节点的左子树是当前节点,//那么其父节点就是当前节点的后继节点。如果不存在,当前节点变为其父节点,继续查找。//原因是把父节点视为中节点,如果中节点是后继节点,必须前一个节点是左子树的最后一个节点。//对于2,4是2的左子树最后的节点,原创 2020-06-10 20:28:14 · 356 阅读 · 0 评论 -
二叉树的前序、中序、后序遍历(递归版 非递归版)
前序遍历:根 左 右中序遍历:左 根 右后序遍历:左 右 根typedef class TreeNode{public: int val; TreeNode* left; TreeNode* right; TreeNode(int x) { this->val = x; right = NULL; left = NULL; } }*Tree;//前序 递归版void Pre(Tree head){ if (head == NULL) return; cout &原创 2020-06-10 20:04:09 · 109 阅读 · 0 评论 -
判断两个单链表相交问题
#include<iostream>#include<vector>#include<stack>#include<math.h>using namespace std;typedef struct ListNode{ int val; ListNode * next;}*List;//判断是否有换,如果有环,则返回入环节点List getLoopNode(List head){ List p = head->next; L原创 2020-06-10 17:43:40 · 76 阅读 · 0 评论 -
单向链表按某值划分成左边小、中间相等、右边大的形式
方法一:开一个数组,放到数组中,然后利用荷兰国旗法排序//单向链表按某值划分成左边小、中间相等、右边大的形式//利用辅助数组void ListSort(List head, int num){ vector<int >v; List p = head; p = p->next; while (p != NULL) { v.push_back(p->val); p = p->next; } int cur = 0; int x = -1; i原创 2020-06-09 18:34:01 · 197 阅读 · 0 评论 -
判断回文链表
//判断回文链表//1.方法一:利用栈结构,把链表倒进去,然后一一弹出比对//2.方法二:快慢指针//快慢指针+栈 减少了额外空间复杂度bool Istrue(List head){ //假设是含有头节点的 head = head->next; while (head== NULL|| head->next == NULL) return true; List p1 = head->next; List p2 = head; while (p1->nex原创 2020-06-09 18:23:22 · 74 阅读 · 0 评论 -
打印两个有序链表的公共部分
打印链表的公共部分类似外排方式(外排不了解的请点击查看算法流程3),原理如下:设置两个指针分别指向链表1和链表2的第一个数,比较指针所指的数的大小(1)如果链表1的数字小,则链表1的指针后移,指向后一个数;(2)如果链表2的数字小,则链表2的指针后移,指向后一个数;(3)如果两个数相等就打印输出当前数,并把指针1,2都向后移一位。bool Findnum(int arr[length][length], int num){ int row = 0;//从有右上角第一行开始 int col =原创 2020-06-09 18:16:52 · 83 阅读 · 0 评论 -
在行列都排序好的矩阵中找数
思路:从右上角第一个数开始找,因为行和列都是排好序的,所以如果要找的数比右上角的数小的话则向左移动,如果比右上角数大的话,则向下移动,然后依次继续比较bool Findnum(int arr[length][length], int num){ int row = 0;//从有右上角第一行开始 int col = length - 1; while (col >= 0 && row <= length - 1) { if (arr[row][col] > n原创 2020-06-09 18:12:47 · 198 阅读 · 0 评论 -
之字打印矩阵
本题之字形输出矩阵,根据方向可分为左下到右上和从右上到左下两个方向输出,实际上可以看成斜向输出,具体方向作为bool变量更改就可以。考虑设置A,B两个点作为辅助,最开始A、B两点都在左上角位置(0,0)(0,0)位置。(1)AB之间的连线就是需要输出的数字,每轮输出后A向右移,B向下移;(2)使用一个bool变量表示打印的方向,每轮打印过后取逆;(3)当A移到最右端则下移,B移到最下端则右移,直到A移void Rotationmatrix(int arr[][height], int a, int原创 2020-06-09 16:15:37 · 130 阅读 · 0 评论 -
旋转正方形矩阵
逐层旋转,右由外向内void Rotationmatrix(int arr[][height], int a, int b, int c, int d){ int times = d - b; for (int i = 0; i < times; i++) { int temp = arr[a][b+i]; arr[a][b + i] = arr[c - i][b]; arr[c-i][b] = arr[c][d - i]; arr[c][d - i] = arr[a + i原创 2020-06-09 15:57:53 · 81 阅读 · 0 评论 -
转圈打印矩阵
利用左上角的点和右下角的点//转圈打印矩阵 肯定是正方形#define height 3#define width 3void print(int arr[][height], int a, int b, int c, int d){ if (a == c) { for (int i = b; i <= d; i++) { cout << arr[a][i]; } } else if (b == d) { for (int i = a; i原创 2020-06-09 15:48:09 · 67 阅读 · 0 评论 -
使用队列实现栈,使用栈实现队列
使用队列实现栈结构,队列是先进先出,栈是后进先出使用两个栈实现队列:(1)一个队列命名为data,所有数据压入此队列。(2)当需要出栈的操作时,把除队列最后一个元素外的所有元素出队列并压入help队列。(3)此时data还有最后一个元素,是最后进来的元素,pop掉(4)交换data和help的引用(5)若继续碰到出栈操作继续2,3步骤,直至size ==0eg:当前data有1,2,3,4,5分别进入队列,出栈时,把除5外1,2,3,4放入help,最后一个5释放掉,交换data与help,此原创 2020-06-09 15:43:55 · 147 阅读 · 0 评论 -
返回栈中最小元素
思路:利用两个栈,一个用来放数据,一个用来放最小值,当两个栈都是空的时候,直接都push,当存放最小值栈不是空的时候,需将要压栈数据和当前栈顶元素大小比较,如果比当前栈顶元素小压入,如果比当前栈顶元素大,则继续压入栈顶元素`///返回栈中最小元素//s1正常压栈,s2是辅助栈void add_num(stack<int>&s1, stack<int>&s2, int num){ s1.push(num); if (s2.empty()) { s2.p原创 2020-06-09 15:36:05 · 126 阅读 · 0 评论 -
使用数组实现队列,使用数组实现栈
使用数组实现栈结构在数组上增加一个index标记,他代表着数组中下一个数该放的位置,从而可以完成进栈,出栈的操作#define length 10void push(int arr[],int a, int &index){ if (index == length) { cout << "栈已满,无法入栈" << endl; } else { arr[index++] = a;//放完元素之后移动index的指向 }}void pop(in原创 2020-06-09 15:21:44 · 108 阅读 · 0 评论 -
堆排序,另一版本
重新写了一遍堆排序,比上一版本更清晰void heapsort(int a[], int size){ while (size > 1) { swap(a[0], a[size - 1]); size--; heapify(a, 0, size); }}void heapify(int a[], int index, int size)//自顶向下{ int left = index * 2 + 1; while (left < size) { int l原创 2020-06-09 15:05:39 · 70 阅读 · 0 评论 -
计数排序应用
////给定一个数组,求如果排序之后,相邻两数的最大差值,///要求时间复杂度O(N),且要求不能用非基于比较的排序。【随机生成9个数,范围在0-99】#define length 9//长度int maxd(int arr[])//最大差值处理函数{ int min = arr[0]; int max = arr[0]; for (int i = 0; i < length; i++) { min = arr[i] < min ? arr[i] : min; max =原创 2020-06-07 17:45:19 · 152 阅读 · 0 评论 -
经典快排,和改进快排
int part(int a[],int l,int r){ int num = a[r]; int cur = l; int x = l-1; int y = r; while (cur < y+1) { if (a[cur] <= num) { swap(a[cur++], a[++x]); } else { cur++; } } return x - 1;}void ClassicQuickRow(int arr[],int l,原创 2020-06-07 15:53:12 · 105 阅读 · 0 评论 -
荷兰国旗问题(c++)
问题描述:给定一个数组,给定一个数num,把数组中大于num的数全都放在右边,小于num的都放在左边分析1.把数组划分为小于等于num的区域和大于num的区域。用变量x代表小于区域的位置。刚开始由于不存在小于等于的区域,则x = -1,表示指向数组-1(不存在)。再设置变量cur作为遍历的位置,刚开始cur = 0指向数组第一个数。2.开始遍历(1)如果cur<=num ,那么把cur当前的元素和小于等于区域的下一个数交换,即++x的位置和cur位置的数交换,cur,x后移;(2)如果cur转载 2020-06-07 11:20:37 · 1403 阅读 · 0 评论 -
小和问题 逆序对问题c++
问题描述:如果一个数组中,右边的数比左边数字大,则构成小和例:1 3 5 6 7中 1<3 11<5 3<5 1 31<6 3<6 5<6 1 3 51<7 3<7 5<7 6<7 1 3 5 6小和为:1+1+3+1+3+5+1+3+5+6利用归并排序(转他人)分析在归并过程中计算小和,实质是如果左数小于右数,则记录1 3 4|2 5/1 3 |4 2|5/1|31.在1|3归并中,1<原创 2020-06-07 10:57:06 · 365 阅读 · 0 评论 -
哈希表
#include<iostream>using namespace std;int Primenum(int n);//查找素数typedef struct LNode *PtrLNode;typedef PtrLNode List;typedef PtrLNode Position;typedef struct TbNOde *HashTable;#define Max...原创 2020-04-20 16:03:20 · 87 阅读 · 0 评论 -
快速排序
//快速排序#include<iostream>using namespace std;void Deal(int a[], int left, int right);void swap(int a[], int t,int b);void QuickSort(int a[], int left, int right);int main(){ int a[10] = {...原创 2020-04-20 09:35:32 · 73 阅读 · 0 评论 -
归并排序非递归
//归并排序(非递归方法)#include<iostream>using namespace std;void Merge(int a[], int temp[], int L, int R, int Rightend);void Merge_Pass(int a[],int temp[],int N,int length);void Merge_Sort(int a[], ...原创 2020-04-17 15:21:27 · 72 阅读 · 0 评论 -
归并排序
/归并排序#include<iostream>using namespace std;//#define Max 100void mergearray(int a[], int first, int mid, int last, int temp[]);//合并两个数组void mergesort(int a[], int first, int last, int temp[...原创 2020-04-16 17:08:08 · 66 阅读 · 0 评论 -
堆排序
#include<iostream>#include<vector>using namespace std;vector<int>v;void Sort(vector<int>&v);void Adjust(vector<int>&v, int s, int m);int main(){ int n, t ...原创 2020-04-15 18:35:41 · 65 阅读 · 0 评论 -
希尔排序
#include<iostream>#include<vector>using namespace std;vector<int>v;void Hill(vector<int>&v);int main(){ int n, t = 0; cout << "输入数字总数" << endl; cin &...原创 2020-04-15 16:52:41 · 66 阅读 · 0 评论 -
直接插入排序
#include<iostream>#include<vector>using namespace std;vector<int>v;void Insert(vector<int>&v);int main(){ int n, t = 0; cout << "输入数字总数" << endl; cin &...原创 2020-04-15 15:41:35 · 57 阅读 · 0 评论 -
简单的选择排序
#include<iostream>#include<vector>using namespace std;vector<int>v;void Select(vector<int>&v);int main(){ int n, t = 0; cout << "输入数字总数" << endl; cin &...原创 2020-04-15 15:21:05 · 62 阅读 · 0 评论 -
冒泡排序
#include<iostream>#include<vector>using namespace std;void Bubble(vector<int>&v);int main(){ vector<int>v; int n, t; cout << "个数" << endl; cin >>...原创 2020-04-15 11:53:44 · 68 阅读 · 0 评论 -
kruskal算法
#include<iostream>#include<algorithm>using namespace std;int k = 0;struct Node{ int from, to, dis;}edge[2000];int farther[2000];int sum = 0;int Nv, Ne;bool cmp(const Node&a,...原创 2020-04-14 15:33:19 · 93 阅读 · 0 评论