--资料来源于网络
C++vector容器:
vector<int> v;//代表vector容器里面是int型数据
vector<vector<int>> vv;//代表容器里面是int型数组,所以vv就是一个二维数组。
vector<int> v;//代表vector容器里面是int型数据
vector<vector<int>> vv;//代表容器里面是int型数组,所以vv就是一个二维数组。
获取元素个数:int len=v.size();//size是真实占了多少,capacity是预留了多少
向里面添加元素:v.push_back(1);
初始化,五种方式:1.初始化为空 vector<int>v;
2.用另一个向量初始化 vector<int>v(v1);
3.初始化大小为n,里面的数据都是i vector<int>v(n,i);
4.构造大小为n的容器,并没有初始化内容 vector<int>v(n);
5.初始化各个元素 vector<int>v{1,3}
使用迭代器遍历容器:(迭代器是一种检查容器内元素并遍历元素的数据类型。其实是指针)
iter1=ivec.bengin(); //将迭代器iter1初始化为指向ivec容器的第一个元素
iter2=ivec.end(); //将迭代器iter2初始化为指向ivec容器的最后一个元素的下一个位置
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++)
判断是否为空:v.empty();
对元素排序:sort(v.begin(),v.end());
反转容器:reverse(v.begin(),v.end())
交换元素:swap(v[i],v[j]);
向里面添加元素:v.push_back(1);
初始化,五种方式:1.初始化为空 vector<int>v;
2.用另一个向量初始化 vector<int>v(v1);
3.初始化大小为n,里面的数据都是i vector<int>v(n,i);
4.构造大小为n的容器,并没有初始化内容 vector<int>v(n);
5.初始化各个元素 vector<int>v{1,3}
使用迭代器遍历容器:(迭代器是一种检查容器内元素并遍历元素的数据类型。其实是指针)
iter1=ivec.bengin(); //将迭代器iter1初始化为指向ivec容器的第一个元素
iter2=ivec.end(); //将迭代器iter2初始化为指向ivec容器的最后一个元素的下一个位置
vector<int>::iterator it;
for(it=v.begin();it!=v.end();it++)
判断是否为空:v.empty();
对元素排序:sort(v.begin(),v.end());
反转容器:reverse(v.begin(),v.end())
交换元素:swap(v[i],v[j]);
判断栈出顺序是否合法:
https://www.cnblogs.com/lovexfr/archive/2016/04/22/5422610.html
bool isStackOutRight(int *stackIn,int *stackOut,int length){
2 stack<int> stackData;//辅助栈
3 int index(0);
4 for (int i = 0;i<length;i++){//遍历整个出栈序列
5
6 if (!stackData.empty() && stackData.top() == stackOut[i])
//辅助栈不空,而且遍历的元素是辅助栈的top元素,需要弹出操作
7 stackData.pop();
8 else { //辅助栈为空,或者不等于首元素,指向压栈操作
9 while(index<length && stackIn[index] != stackOut[i])
10 stackData.push(stackIn[index++]);
11 if (index == length)//这里是关键,说明在压栈序列中从index开始往后遍历,没有找到该元素,该出栈序列不正确
12 return false;
13 else
14 index++;
15 }
16 }
17 return true;//整个for循环能正常结束(没有遇到return false),说明出栈序列正确
18 }
https://www.cnblogs.com/lovexfr/archive/2016/04/22/5422610.html
bool isStackOutRight(int *stackIn,int *stackOut,int length){
2 stack<int> stackData;//辅助栈
3 int index(0);
4 for (int i = 0;i<length;i++){//遍历整个出栈序列
5
6 if (!stackData.empty() && stackData.top() == stackOut[i])
//辅助栈不空,而且遍历的元素是辅助栈的top元素,需要弹出操作
7 stackData.pop();
8 else { //辅助栈为空,或者不等于首元素,指向压栈操作
9 while(index<length && stackIn[index] != stackOut[i])
10 stackData.push(stackIn[index++]);
11 if (index == length)//这里是关键,说明在压栈序列中从index开始往后遍历,没有找到该元素,该出栈序列不正确
12 return false;
13 else
14 index++;
15 }
16 }
17 return true;//整个for循环能正常结束(没有遇到return false),说明出栈序列正确
18 }
串中任意个连续的字符组成的子序列称为该串的子串。空串和本身都算做本字符串的字串
printf输出格式:
“%-5c” 表示不足五个字节,就在后面加空格
“%-5.2f” 表示浮点数的小数点后要有2位,整个浮点数不足5个字,,后面用空格补齐。
“%-5c” 表示不足五个字节,就在后面加空格
“%-5.2f” 表示浮点数的小数点后要有2位,整个浮点数不足5个字,,后面用空格补齐。
图:用二维数组表示的无圈的有向图
https://blog.csdn.net/smarter_shability/article/details/69664755
vertex顶点 edge边
https://blog.csdn.net/smarter_shability/article/details/69664755
vertex顶点 edge边
#include<stdio.h>
#define MAX_VERTEX 4
typedef char DataType; //图中元素的目标数据类型
typedef struct
{
DataType vertexArr[MAX_VERTEX]; //顶点元素数组
int arcArr[MAX_VERTEX][MAX_VERTEX]; //弧矩阵二维数组
}ArrayGraph;
void ArrayGraph_init(ArrayGraph *pGraph);
void ArrayGraph_create(ArrayGraph *pGraph);
void ArrayGraph_show(ArrayGraph *pGraph);
int main()
{
ArrayGraph g;
ArrayGraph_init(&g);
ArrayGraph_create(&g);
ArrayGraph_show(&g);
return 0;
}
//初始化为一个无圈图 ,也就是弧矩阵中,主对角线元素都是0
void ArrayGraph_init(ArrayGraph *pGraph)
{
for (int i = 0; i < MAX_VERTEX; i++)
pGraph->arcArr[i][i] = 0;
}
void ArrayGraph_create(ArrayGraph *pGraph)
{
for (int i = 0; i < MAX_VERTEX; ++i) //填充顶点数组
{
printf("输入第%d个顶点值\n",i+1);
scanf(" %c",&(pGraph->vertexArr[i]));
}
for (int j = 0; j <MAX_VERTEX; ++j) //填充边关系
{
for (int i = j+1; i < MAX_VERTEX; ++i)
{
printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",pGraph->vertexArr[i],pGraph->vertexArr[j]);
scanf("%d",&( pGraph->arcArr[j][i]));
printf("若元素%c有指向%c的弧,则输入1,否则输入0\t",pGraph->vertexArr[j],pGraph->vertexArr[i]);
scanf("%d",&( pGraph->arcArr[i][j]));
}
}
}
void ArrayGraph_show(ArrayGraph *pGraph)
{
printf("\n\n顶点元素如下\n");
for (int i = 0; i < MAX_VERTEX; ++i)
{
printf("%-5c", pGraph->vertexArr[i]);
}
printf("\n\n");
puts("弧矩阵如下\n\n");
printf("%-2c",' ');
for(int i=0;i<MAX_VERTEX;++i)
printf("%-5c",pGraph->vertexArr[i]);
putchar('\n');
for (int j = 0; j <MAX_VERTEX; ++j)
{
printf("%-2c",pGraph->vertexArr[j]);
for (int i = 0; i < MAX_VERTEX; ++i)
{
printf("%-5d",pGraph->arcArr[i][j]);
}
putchar('\n');
}
putchar('\n');
}
偏序:集合内只有部分元素在这个关系下是可以比较的
https://blog.csdn.net/liuchuo/article/details/51986226
简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序
通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网
例如,假定一个计算机专业的学生必须完成图3-4所列出的全部课程。在这里,课程代表活动,学习一门课程就表示进行一项活动,学习每门课程
的先决条件是学完它的全部先修课程。如学习《数据结构》课程就必须安排在学完它的两门先修课程《离散数学》和《算法语言》之后。学习《
高等数学》课程则可以随时安排,因为它是基础课程,没有先修课。若用AOV网来表示这种课程安排的先后关系,则如图3-5所示。图中的每个顶
点代表一门课程,每条有向边代表起点对应的课程是终点对应课程的先修课。图中的每个顶点代表一从图中可以清楚地看出各课程之间的先修和
后续的关系。如课程C5的先修课为C2,后续课程为C4和C6。 [2]
一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行。如图3-6是一个具有三个顶点的回路
,由<A,B>边可得B活动必须在A活动之后,由<B,C>边可得C活动必须在B活动之后,所以推出C活动必然在A活动之后,但由<C,A>边可得C活动必须
在A活动之前,从而出现矛盾,使每一项活动都无法进行。这种情况若在程序中出现,则称为死锁或死循环,是应该必须避免的。
在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列
(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological
sort)。
AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
由AOV网构造出拓扑序列的实际意义是:如果按照拓扑序列中的顶点次序,在开始每一项活动时,能够保证它的所有前驱活动都已完成,从而使整
个工程顺序进行,不会出现冲突的情况。 [2]
的先决条件是学完它的全部先修课程。如学习《数据结构》课程就必须安排在学完它的两门先修课程《离散数学》和《算法语言》之后。学习《
高等数学》课程则可以随时安排,因为它是基础课程,没有先修课。若用AOV网来表示这种课程安排的先后关系,则如图3-5所示。图中的每个顶
点代表一门课程,每条有向边代表起点对应的课程是终点对应课程的先修课。图中的每个顶点代表一从图中可以清楚地看出各课程之间的先修和
后续的关系。如课程C5的先修课为C2,后续课程为C4和C6。 [2]
一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行。如图3-6是一个具有三个顶点的回路
,由<A,B>边可得B活动必须在A活动之后,由<B,C>边可得C活动必须在B活动之后,所以推出C活动必然在A活动之后,但由<C,A>边可得C活动必须
在A活动之前,从而出现矛盾,使每一项活动都无法进行。这种情况若在程序中出现,则称为死锁或死循环,是应该必须避免的。
在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列
(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological
sort)。
AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
由AOV网构造出拓扑序列的实际意义是:如果按照拓扑序列中的顶点次序,在开始每一项活动时,能够保证它的所有前驱活动都已完成,从而使整
个工程顺序进行,不会出现冲突的情况。 [2]
单向散列函数:windows的数字签名用了单向散列函数
又称单向Hash函数、杂凑函数,就是把任意长的输入消息串变化成固定长的输出串且由输出串难以得到输入串的一种函数。这个
输出串称为该消息的散列值。一般用于产生消息摘要,密钥加密等.
散列函数几种算法:查找时,只需根据这个对应关系f找到给定值K的像f(K)
1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key +
b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。
2.
数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很
大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数
字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
3.
平方取中法:当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为
:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。 [2]
例:我们把英文字母在字母表中的位置序号作为该英文字母的内部编码。例如K的内部编码为11,E的内部编码为05,Y的内部编码为25,A的内部
编码为01,
B的内部编码为02。由此组成关键字“KEYA”的内部代码为11052501,同理我们可以得到关键字“KYAB”、“AKEY”、“BKEY”的内部编码。之后对关键字
进行平方运算后,取出第7到第9位作为该关键字哈希地址,
4.
折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加可以有
移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后
对齐相加。
5. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD
p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义
词。
1. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key +
b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。
2.
数字分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很
大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数
字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
3.
平方取中法:当无法确定关键字中哪几位分布较均匀时,可以先求出关键字的平方值,然后按需要取平方值的中间几位作为哈希地址。这是因为
:平方后中间几位和关键字中每一位都相关,故不同关键字会以较高的概率产生不同的哈希地址。 [2]
例:我们把英文字母在字母表中的位置序号作为该英文字母的内部编码。例如K的内部编码为11,E的内部编码为05,Y的内部编码为25,A的内部
编码为01,
B的内部编码为02。由此组成关键字“KEYA”的内部代码为11052501,同理我们可以得到关键字“KYAB”、“AKEY”、“BKEY”的内部编码。之后对关键字
进行平方运算后,取出第7到第9位作为该关键字哈希地址,
4.
折叠法:将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(去除进位)作为散列地址。数位叠加可以有
移位叠加和间界叠加两种方法。移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后
对齐相加。
5. 随机数法:选择一随机函数,取关键字的随机值作为散列地址,通常用于关键字长度不同的场合。
6. 除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD
p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义
词。
处理冲突:
1. 开放寻址法:Hi=(H(key) + di) MOD m,
i=1,2,…,k(k<=m-1),其中H(key)为散列函数,m为散列表长,di为增量序列,可有下列三种取法:
1.1. di=1,2,3,…,m-1,称线性探测再散列;
1.2. di=1^2,-1^2,2^2,-2^2,⑶^2,…,±(k)^2,(k<=m/2)称二次探测再散列;
1.3. di=伪随机数序列,称伪随机探测再散列。
递归工作栈里面包括返回地址、本层的局部变量和递归调用的形参代换用实参