![](https://img-blog.csdnimg.cn/20190927151101105.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
基础数据结构和算法
学习基础数据结构和算法,代码主要参考书籍、mooc和博客等
星-耀
A platform for communication
展开
-
基础排序:归并排序
2路归并。采用分治的思想:将数组区间不断二分,直至每个区间只有一个元素。单个元素自然是有序的。然后将有序区间两两合并,最后得到一个有序数组。用递归来实现分治。void merge(int *arr, int L1, int R1, int L2, int R2){ // 申请辅助空间用于临时保存合并后的序列 int *temp = malloc(sizeof(int)*(R2-L1+1)), index = 0; // 有序合并左右子区间:如果左右子区间不等长,最后有一方会有原创 2021-09-02 14:58:06 · 82 阅读 · 0 评论 -
堆与堆排序
堆是一颗完全二叉树。如果父节点的值小于等于孩子节点的值,则称为小根堆;否则称为大根堆。小根堆的接口定义与实现:#define HEAPMAXSIZE 100typedef int HElemType;typedef struct{ HElemType *base; int capacity; int length;}MinHeap;// 交换两元素的值void swap(HElemType *a, HElemType *b){ HElemType tem原创 2021-08-31 21:14:29 · 117 阅读 · 0 评论 -
重建二叉树
节点定义:typedef char ElemType;typedef struct tagBitNode{ char data; struct tagBitNode *left; struct tagBitNode *right;} BitNode;函数定义:// 生成新节点BitNode *newBitNode(ElemType data){ BitNode *root = (BitNode *)malloc(sizeof(BitNode));原创 2021-08-31 17:16:38 · 75 阅读 · 0 评论 -
二叉树——链式存储
一、二叉树结构定义二叉树的节点定义:typedef char ElemType;typedef struct tagBitNode{ char data; struct tagBitNode *left; struct tagBitNode *right;} BitNode;手动构建一个如图所示的二叉树。// 生成新节点BitNode *newBitNode(ElemType data){ BitNode *bitNode = (BitNode *)ma原创 2021-08-28 17:07:27 · 371 阅读 · 0 评论 -
认 识 树
一、树的基本术语节点的度:节点的孩子的个数。(1)度为0的节点:叶子节点(2)度不为0的节点:分支节点树的度:树的节点的度的最大值。树的高度(深度):树的节点所在的最大层次。二、二叉树二叉树:每个节点最多只能有两个孩子的树。设二叉树的根节点所在为第一层。性质 1:二叉树的第iii层最多有2i−12^{i-1}2i−1个节点。等比数列公式:an=a1∗qn−1a_n=a_1*q^{n-1}an=a1∗qn−1性质2:深度为kkk的二叉树最多有2k−12^k-12k−1个节点。原创 2021-08-28 15:28:34 · 183 阅读 · 0 评论 -
基本排序——冒泡排序
思路就是,重的下沉,轻的上浮。(1)n个数需要n-1躺排序(2)每趟排序中,对相邻数两两进行比较,重的下沉。第一趟有n个数待排序,需要比较n-1次;第二趟有n-1个数待排序,需要n-2次比较;…;第n-1躺只有两个数待排序,需要1次比较。// 朴素冒泡排序void bubbleSort(int *arr, int length){ // length个数需要lenght-1次冒泡过程完成排序 for(int i=1; i<length; i++) {原创 2021-08-28 10:15:51 · 116 阅读 · 0 评论 -
栈的应用——括号匹配
涉及的括号有:圆括号()、方括号[ ] 、大括号{ } 。正常情况下,对于左括号,直接入栈;对于右括号,其与栈顶的左括号类型相匹配,直接弹出栈顶左括号。遍历完字符串后,所有括号都能正确匹配,并且栈空。出错的情况:(1)字符串扫描过程中,栈空,说明右括号多了,或者漏写了左括号。(2)字符串扫描过程中,栈不空,但括号类型不匹配。(3)字符串扫描完后,栈非空,说明漏写了右括号,或者多写了左括号。#include <iostream>#include <stack>#inc原创 2021-08-27 20:58:52 · 344 阅读 · 0 评论 -
链式队列——单链表实现
1,结构定义typedef char QueueElement;typedef struct tagLinkQueueNode{ QueueElement data; struct tagLinkQueueNode *next;}LinkQueueNode;typedef struct tagLinkQueue{ LinkQueueNode *front; LinkQueueNode *rear; int length;}LinkQueue;2,初原创 2021-08-25 18:39:30 · 310 阅读 · 0 评论 -
循环队列——数组实现
一、循环队列结构定义#define MAXQSIZE 100 // 队列最大长度,实际可用空间要少一个typedef char QElemType;typedef struct{ QElemType *base; int front; //始终指向队头 int rear; //始终指向非空队列队尾的下一个元素}CircularQueue;借图一用...原创 2021-08-24 21:22:06 · 479 阅读 · 0 评论 -
基本排序算法——直接插入排序
算法过程:对于有N个元素的序列,arr[0] ~ arr[n-1]。前i个已经有序,arr[0]~arr[i-1],arr[i] 及之后的元素无序。现在将无序元素arr[i]插入到前面的有序部分中。将arr[i]记为temp,与前面有序部分的元素依次比较。若temp小于前面的元素,则将前面小于temp的元素后移,最后将temp放入合适的位置。void insertSort(int *arr, int length){ for(int i=1; i<length; i++) {原创 2021-08-21 13:36:10 · 314 阅读 · 0 评论 -
中缀表达式求值
中缀表达式求值主要分为两大步:1,将中缀表达式转换为后缀表达式2,计算后缀表达式一、中缀表达式转后缀表达式在转换中,需要用到栈来临时存储操作符:加、减、乘、除、左括号。#include <cstdio>#include <string>#include <stack>#include <queue>using namespace std;// 去除字符串中的空格void trim(string &s){ int index原创 2021-08-19 16:40:10 · 2804 阅读 · 0 评论 -
栈——链式存储
链栈是基于单链表实现的,所以要先掌握链表的基本操作:遍历、增加节点、删除节点等。1,链栈的结构链栈的节点,负责保存元素的值。typedef struct tagLinkStackNode{ char data; //数据域 struct tagLinkStack *next;//指针域}LinkStackNode;链栈中维护一个长度变量lengthlengthlength和栈顶指针toptoptop。typedef struct tagLinkStack{ int length;原创 2021-08-17 21:54:39 · 161 阅读 · 0 评论 -
栈——数组实现
栈具有后进先出的特性。栈的应用:数学表达式求值、函数调用与递归、深度优先搜索、括号匹配等。1,栈的结构定义简单起见,定义一个字符栈。toptoptop表示栈顶元素的索引。datadatadata数组用来存储栈的元素。#define STACKMAXSIZE 100typedef struct tagSqStack{ char data[STACKMAXSIZE]; int top;}SqStack;2,初始化使用栈时,必须初始化。对未初始化的栈的操作是未定义的。当栈为空栈时,令t原创 2021-08-17 17:38:40 · 129 阅读 · 0 评论 -
大整数运算
int:−2,147,483,648int:-2,147,483,648int:−2,147,483,648 ~ 2,147,483,6472,147,483,6472,147,483,647大整数是超出基本数据类型表示范围的数。一、大整数的表示定义一个结构体:// 大整数用结构体表示typedef struct tagBigInt{ int d[1000]; int len;}BigInt;d的每一个元素都代表大整数的一位,len记录了大整数的长度。在定义结构体变量后,原创 2021-08-11 16:18:22 · 1343 阅读 · 0 评论 -
素数的判断
素数是指除了1和它本身以外,不能被其他数整除的一类数。注意:1不是素数,也不是合数。一、素数的判断如何判断一个正整数是否是素数?设一个数为nnn。如果在222~n−1n-1n−1中存在nnn的约数,设为a,ba,ba,b。则有a⩽n⩽ba \leqslant \sqrt{n} \leqslant ba⩽n⩽b故只需要判定nnn能否被222~n\sqrt{n}n中的数整除,即可判定nnn是否为素数。int isPrime(int n){ if(n<=1)//判断特例原创 2021-08-08 15:29:34 · 486 阅读 · 0 评论 -
分数四则运算
一、分数的表示与化简用结构体表示分数。typedef struct tagFraction{ int up; int down;}Fraction;作一个约定:①使分母down非负。如果分母为负数,那么令分子和分母都变为相反数。②如果分数为0,那么令分母down为1。③分子和分母没有除了1以外的公约数。可以令分子、分母同时除以最大公约数来实现。化简分数使其满足这三条规则。//求最大公约数,辗转相除法递归实现int gcd(int a, int b){ //递原创 2021-08-08 10:29:19 · 340 阅读 · 0 评论 -
最大公约数与最小公倍数
一、最大公约数使用辗转相除法求最大公约数,递归实现://求最大公约数,辗转相除法递归实现int gcd(int a, int b){ //递归边界 b=0 if(0 == b) { return a; } else { return gcd(b, a%b); }}二、最小公倍数在最大公约数的基础上求最小公倍数。若a,ba,ba,b的最大公约数为ddd,则最小公倍数为a∗b/da*b/da∗b/d。防止乘积原创 2021-08-07 15:38:19 · 47 阅读 · 0 评论 -
随机选择算法
如何从一个无序数组中找到第KKK大的数?方案一:对数组排序,然后取出第KKK大的数。需要O(nlogn)O(nlogn)O(nlogn)的时间复杂度。方案二:随机选择算法,对任何输入都可以达到O(n)O(n)O(n)的时间复杂度。原理类似于随机快速排序void swap(int *a, int *b){ int temp = *a; *a = *b; *b = temp;}int randPartion(int *arr, int left, int right){原创 2021-08-07 15:11:12 · 414 阅读 · 0 评论 -
基础排序:快速排序
一、快速排序快排思路:①选择最左侧的元素作为主元,经过调整顺序,使得主元左侧的元素均不大于主元,右侧的元素均大于主元②对主元的左侧和右侧分别递归进行①的调整,直到区间的左右侧相遇// 划分区间:划分后,arr左侧所有元素不大于arr[left], 右侧所有元素均大于arr[left]int partion(int *arr, int left, int right){ // 划分区间 int temp = arr[left]; //用临时变量保存left位置的值,此时可将left原创 2021-08-06 11:10:51 · 124 阅读 · 0 评论 -
快速幂算法
SSS表示ppp的二进制权位序列:2k,...,23,22,21,202^k,...,2^3,2^2,2^1,2^02k,...,23,22,21,20。BBB表示ppp的二进制序列。bpb^pbp可以表示成bp=∏i=0kbSk∗Bkb^p =\prod_{i=0}^{k} b^{S_k*B_k}bp=i=0∏kbSk∗Bk以3133^{13}313为例。5的二进制序列为1101,从右开始数,0号位为1,1号位为0,2号位为1,3号位为1。则B=1,1,0,1B=1,1,0,1B=1,1,0原创 2021-08-03 17:10:56 · 90 阅读 · 0 评论 -
字符串Hash基础
字符串hash是指将一个字符串s映射为一个整数,使得该整数尽可能唯一地代表字符串s。涉及知识:进制转换、秦九韶算法。假设字符串仅包含大写字母,范围A-Z。将A-Z看作0-25的26进制数,再转换为我们需要的10进制数。// 字符串仅含大写字母,将字符串转换为整数int hashFunc(const char *s, int length){ int id = 0; for(int i=0; i<length; ++i) { id = id*26 + s原创 2021-08-03 08:16:47 · 87 阅读 · 0 评论 -
基本排序算法:选择排序
算法过程如图所示,(图片来自网络)代码:void swapInt(int *p, int *q){ int temp = *p; *p = *q; *q = temp;}void selectSort(int *arr, int length){ for(int i=0; i<length; ++i) { int minIndex = i; for(int j=i+1; j<length; ++j) { if (arr[j]<arr[minInde原创 2021-07-31 14:17:22 · 60 阅读 · 0 评论 -
基本查找算法
一、顺序查找适用于查找无序数据,时间复杂度为O(n).算法过程:从一端开始逐元素与给定的key值比较。(1) 无哨兵的算法int SeqSearch(int *arr, int length, int key){ for(int i=0; i<length; --i) { if(arr[i] == key) { return i; } } return -1; /原创 2021-07-21 20:29:56 · 273 阅读 · 0 评论