数据结构复习过程中的笔记_顺序队列满了会怎么样-程序员宅基地

技术标签: 算法  笔记  数据结构  b树  

知识点盲区

主要为在做题过程中发现的知识点盲区,自己的找到的坑,逐步一点一点慢慢的填上
0.1 队列
顺序队列空:frontrear
顺序队列满:front
rear,会出现假溢出情况
因为顺序队列是按照头出尾进的操作方式存储元素,当元素存满队列,从队头出队元素到队列非空,在执行入队列操作时,队列实际上是没有满,还有大量的空闲元素,但是已经满足rear==frot的条件,我们把这种现象叫做假溢出,为了解决这种问题引出了循环队列的概念。

初始时:front=rear=0
循环队列入队:rear=(rear+1)%MAXSIZE
循环队列出队:front=(front+1)%MAXSIZE
循环队列长度:(rear-front+MAXSIZE)%MAXSIZE
循环队列队空:frontrear
循环队列队满:
(1)牺牲一个单元来区分队空或队满,入队列时候少用一个队列单元
队满:(rear+1)%MAXSIZE
front
队空:front=rear
元素个数:(rear-front+MAXSIZE)%MAXSIZE
(2)增加一个元素表示数据成员个数,
队满:sizeMAXSIZE,frontrear
队空:size0,frontrear
(3)增加tag数据成员,区分队空还是满
tag0时,若因删除导致frontrear,则为空
tag1时,若因插入导致frontrear,则为满

0.2 链队列
不带头结点的队列front指向第一个元素,rear指向最后一个元素,当队列空时rear=front=null
带头结点的队列front指向头结点,rear指向最后一个元素,当队列空时,rear、front都指向头结点

void InitQueue(LinkQueue *Q)
{
    
		Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
		Q.front->next = NULL;
}
bool IsEmpty(LinkQueue Q)
{
    
		if(Q.front == Q.rear)
				return true;
		else
				return false;
}
void EnQueue(LinkQueue &Q,ElemType x)
{
    
		LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
		s->data = x;
		s->next = NULL;
		Q.rear->next = s;
		Q.rear = s;
}
void DeQueue(LinkQueue &Q,ElemType &x)
{
    
		if(Q.front == Q.rear)
				return false;
		x = p->data;
		Q.front->next = p->next;//指向出队元素的后一个
		if(Q.rear == p)
				Q.rear = Q.front;
		free(p);
		return true;
}

0.3 双端队列
双端队列是指两端都可以进行插入和删除操作的队列
输出受限的双端队,允许在一端进行插入和删除,另外一端只允许插入
输入受限的双端队,允许在一端进行插入和删除,另外一端值允许删除

1、线性表的基本操作
线性表的操作都是从第i个位置,而不是下标,
插入元素需要后移动n-i+1
删除元素需要移动n-i
查找元素i
2、已知邻接矩阵,计算i结点的入度,删除所有i结点出发的狐头
邻接矩阵行是出度,列是入度
删除i结点出发的边,将邻接矩阵中i行的元素都置为0即可删除边

有向图的邻接矩阵i行是出度,j列是入度,度是顶点入度和出度之和
无向图的邻接矩阵i行或j列为某个结点的度,

3、二叉排序树的中序遍历是递增序列
(1)非空二叉树上的叶子结点数等于度为2的结点数加1:n0=n2+1
(2)非空二叉树上第k层至多有2^(k-1)个结点
(3)高度为h的二叉树至多有2^h-1个结点
(4)高度为log2n+1
1)当i>i时,结点i的双亲结点编号为i/2,当i为偶数时,双亲为n/2,是左孩子,当i为奇数时,双亲为(i-1)/2,是右孩子
2)当2i<=n时,结点i的左孩子编号为2i,否则无左孩子
3)当2i+1<=n时,结点i的右海子编号为2i+1,否则无右孩子
4、拓扑排序的作用
判断有向图是否有环路,求有向图的最长路径
5、数据结构的逻辑结构
三对角矩阵
前n-1行有:3(n-2)+2=3i-4个元素
第n行aij元素前有多少个元素:(j-i)+1

6、广义表转化为树
根据广义表构建二叉树
7、排序的插入次数
最好情况下,序列已经有序,每次选取递增序列进行比较,不需要移动元素,时间复杂度为O(n)
最坏情况下,序列逆序,每次都要比较,每次都要移动,比较2+3+…+n次,移动i+1次,哨兵操作两次,移动元素i-1次
稳定性,由于每次插入元素从事从后向前先比较在移动,所以不会发生位置变化

折半插入的比较次数
折半插入仅仅减少了比较次数O(nlog2n),时间复杂度还是O(n2)

冒泡排序
最好情况下,序列有序,第一趟检测到有序后flag为false则表明没有元素交换,从而直接退出,比较n-1次,移动0次,时间复杂度为O(n)
最坏情况下,序列逆序,进行n-1趟排序,第i趟排序进行n-i次比较,每次比较后移动3次交换元素Swap函数,
进行n-1趟比较,比较n-i次,移动3(n-i)次,时间复杂度为O(n2)
稳定性,当i>j时且A[i] == A[j]时不会发生交换,稳定排序,产生的序列是全局有序的

快速排序
最好情况下,元素基本逆序,递归树平衡,时间复杂度O(n2),空间复杂度O(log2n)
最坏情况下,元素在两个取于分别是n-1个和0个元素,元素基本有序,时间复杂度O(n2),空间复杂度O(n)
稳定性,在划分过程中,若区间内有小于基准的值,则在交换过程中相对位置会发生变化
排序后不会产生有序子序列,但是每趟排序后基准元素会被放在最终位置

选择排序
最好情况下,序列有序,比较n趟,比较i次(找最小元素),共n(n-1)/2次
最坏情况下,序列无序,比较n趟,比较i次,共n(n-1)/2次,因此时间复杂度始终为O(N2)
稳定性,在第i趟找最小元素后,可能会导致相同关键字元素的相对位置发生改变,因此是不稳定算法

堆排序
调整时间与树高有关,在n个元素的堆中,比较次数不超过4n,比较的时间复杂度为O(n)
建堆的时间为O(n),调整n-1次,每次O(h),h为树高,故时间复杂度为O(nlog2n)
适合于关键字特大的情况,不稳定,因为构建堆的过程中可能会交换相对位置

归并排序
算法思想,按照2,4,8,16,…,的间隔不断将多个有序子列表进行合并排序。
最好情况下,每趟的时间复杂度为O(n),需要进行log2n趟,故时间复杂度为O(nlog2n)

基数排序
将插入的记录按照插入顺序连接起来。
空间效率,一趟排序需要辅助空间为r(r个队列),O,r个关键字,d表示数字最大的位数
时间效率,基数需要进行d趟分配和收集,一趟分配需要O(n),一趟收集需要O,一趟的时间复杂复杂度为O(n+r),时间复杂度为O(d(n+r))。
8、堆的性质,建立,调整,插入

大根堆、小根堆:堆顶的元素都比双亲大或小,是完全二叉树
堆的建立,根据序列按照层序填充,插入的元素在最后
堆的调整,堆[n/2]-1个结点不断调整

9、哈夫曼树的性质
10、哈夫曼树的叶子结点的个数
11、二分查找的判定树的高度
log2n+1
12`、满二叉树
除了叶子结点外,每个结点的度都为2,左孩子结点为n/2,右孩子结点为2i+1
12、完全二叉树的性质
(1)i<n/2,则结点i为分支结点,否则为叶子结点
(2)叶子结点只可能在最大的两层数先,对于最大层次中的叶子结点,都依次排到该层的最左边
(3)若有度为1的结点,则只可能有1个,且该结点只有左孩子,没有右孩子
(4)按照层序编号,一旦出现某结点为叶子结点或只有左孩子,则编号大于i的结点均为叶子结点
(5)n为奇数时,每个分支结点都有左孩子和有孩子,n为偶数时编号最大的分支结点(n/2)只有左孩子,没有右孩子
13、冒泡排序的比较次数
冒泡排序
最好情况下,序列有序,第一趟检测到有序后flag为false则表明没有元素交换,从而直接退出,比较n-1次,移动0次,时间复杂度为O(n)
最坏情况下,序列逆序,进行n-1趟排序,第i趟排序进行n-i次比较,每次比较后移动3次交换元素Swap函数,
进行n-1趟比较,比较n-i次,移动3(n-i)次,时间复杂度为O(n2)
稳定性,当i>j时且A[i] == A[j]时不会发生交换,稳定排序,产生的序列是全局有序的
14、二分查找的平均查找长度
二叉排序树为平衡二叉树则高度为O(log2n),若为单只树(变成了链表)则为O(n)

二叉排序树生成树不唯一,当序列不同时树不同,二分查找的树唯一
15、三维数组的存储地址
16、关键路径的相关概念理解
AOE网特性:
(1)只有在某顶点所代表的事件发生后,从该顶点出发的各有向边代表的活动才能开始。
(2)只有在进入某顶点的各个有向边所代表的活动都结束时,该顶点所代表的事件才能发生
(3)AOE网中仅有一个入度为0的顶点,称为源点,表示整个工程的开始,仅仅有一个出度为0的点,称为汇点
从源点到汇点的路径中,具有最大长度的路径称为关键路径,关键路径上的活动称为关键活动。
完成整个工程的最短路径就是关键路径的长度,即关键路径上活动花费开销和,因为关键活动影响了工程的事件,若关键活动不按时完成,则会影响工程的完成时间
关键活动相关概念
1)事件最早发生事件ve
从前往后取最大,决定了所有v开始活动的最早时间,max
2)事件最晚发生事件vl
从后往前取最小,决定了所有v开始活动最迟发生时间,min
3)活动最早开始时间e
该弧 起点 表示的事件,最早发生时间,<k,j>表示边i,e(i)=ve(k)
4)活动最迟开始时间l
该弧 终点 表示的事件,最迟发生时间与该活动所需要时间的差,<k,j>表示边i,l(i)=vl(j)-weight(i)
5)最迟开始时间和最早开始时间差d

16.1、最短路径相关概念
单源最短路径:dijkstra,不适用带有负值的图,因为最短路径长度加上这条负值的俄结果可能小于a原先确定的最短路径长度,则无法进行更新。
时间复杂度:邻接矩阵,为O(v^2)
16.2、拓扑排序
有向图的无环图的排序
(1)每个顶点只出现一次
(2)若顶点A在序列中排在顶点B前面,则在图中不存在顶点B到顶点A的路径
拓扑排序是对有向无环图的一种排序,使得若存在一条边从顶点A到顶点B的路径,在排序中顶点B出现在顶点A的后面

bool Topological(Graph G)
{
    
		InitStack(s);
		for(int i = 0;i < G.vexnum;i++)
		{
    
				if(indegree[i] == 0)//将所有入度为0的结点入栈
						push(s,i);
		}
		int count = 0;
		while(!IsEmpty(s))//DFS思想
		{
    
				pop(s,i);//出栈
				print[count++] = i;//访问
				for(p = G.vertices[i].firstarc;p >= 0;p = p ->nextarc)//所有指向i的顶点入度减1,如果减完后的顶点度为0则入栈。
				{
    
						v = p->adjvex;
						if(!(--indegree[v]))//入度为0则入栈
						{
    
								push(s,v);
						}
				}
		}
		if(count < G.vexnum)
				return false;
		else
				return true;
}
bool Topo(Graph G)
{
    
		InitStack(s);
		for(i = 0;i < G.vexnum;i++)
		{
    
					if(indegree[i] == 0)
					{
    
								push(s,i);
					}	
		}
		int count = 0;
		while(!IsEmpty(s))
		{
    
					pop(s,i);
					print[count++] = i;
					for(w = FirstNeighbor;w >= 0;w = NextNeighbor(G,w,v))
					{
    
								if(!(--indegree[v]))
										push(s,v);
					}
		}
		if(count < G.vexnum)
				return false;
		else
				return true;
}

17、二叉树空链域的问题

n个结点的二叉链表中有n+1个空链域,n个结点有2n域,除了根结点外每个结点都被指向故有n-1个被占用
空=2n-(n-1)=n+1个

18、顺序查找的查找长度
查找成功:每个元素的比较次数n-i+1次,共n个元素,每个元素查找概率为1/n,(1+2+…+n)1/n,ASL=(n+1)/2
查找失败:每个元素比较次数为n+1次,ASL=n+1

有序表的顺序查找
n个结点,有n+1个查找失败的结点,n+1空指针域
除了第一个结点以外每个结点都有指针值指向该结点2n-(n-1)=2n-n+1=n+1个空指针域

查找成功:每个元素比较n-i+1次,共n个元素,每个元素查找概率为1/n,(1+2+…+n)1/n,ASL=(n+1)/2
查找失败:查找失败次数等于父圆形结点所在层数,最后一层有2个查找失败结点
每个查找失败的概率为1/(n+1),(1+2+…+n+n)/n+1=n/2 + n/(n+1)

在这里插入图片描述

**18.2、折半查找 **

int Binary_Search(SeqList L,ElemType key)
{
    
		int low = 0,high = L.len-1,mid;
		while(low <= high)
		{
    
				mid=(low+high)/2;
				if(L.elem[mid] == key)
						return mid;
				else if(L.elem[mid] > key)
						high = mid - 1;
				else
						low = mid + 1;
		}
		return -1;
}

n个元素,判定树有n个圆形结点和n+1个非圆形结点,是一棵平衡二叉树
查找成功:查找长度为根结点到目的结点路径上结点个数,也就是层高
查找失败:查找失败为根结点到目的结点上父亲结点个数,也就是层高
查找成功平均查找长度ASL=1/n(11+22+…+h2^h-1)=n+1/n log2(n+1) = log2(n+1) - 1=树高(多种表示方法)
时间复杂度为O(log2n)
查找成功平均查找长度ASL=(园形结点个数
层数)/方形结点个数
查找失败平均查找长度ASL=(方形结点个数*层数)/方形结点个数
18.3、分块查找
分块查找:块内无序,块间有序
第一块中的最大关键字小于第二块中所有关键字,
第二块中的最大关键字小于第三块中所有关键字。。
索引表,索引表中有每个元素块中的最大关键字和各个块的第一个元素地址,索引表有序排列
平均查找长度ASL=L1+Ls

将长度为n的查找表均匀的分成b块(索引表),每块s的元素(块内),此时b和s相当于n
块内和索引在表中都采用顺序查找: ASL=L1+l2=(b+1)/2 + (s+1)/2
快内采用顺序查找、索引表采用折半查找:ASL=L1+Ls = log2(b+1) + (s+1)/2
19、三元组相关概念
20、k叉树的性质
树的基本性质:
(1)树中结点数等于所有结点度数之和+1
(2)度为m的树中第i层上最多有m^(i-1)个结点
(3)高度为h的m叉树中最多有(m^k - 1)/(m-1)个结点
(4)具有n个结点的m叉树最小高度为logm(n(m-1))+1

总结点数=n0+n1+n2+…+nm
总分支数=0n0+1n1+2n2+mnm(度为m的结点引出m条分支)
总结点数=总分支数+1
20、哈夫曼树
哈夫曼树中只有度为0和度为2的结点
度为m的哈夫曼树只有度0和m的结点,设度为m的结点有nm个,度为0的结点有n0个,结点总数为n,n=n0+nm
n个结点的哈夫曼树有n-1条分支,mn = n-1=nm+n0-1,整理得(m-1)nm=n0-1,nm=(n-1)/(m-1)

特点
(1)初始结点都为叶子结点,权值越小根根结点的路径月长
(2)构造过程中新建了n-1个结点(双分支结点),哈夫曼树结点总数为n+n-1=2n-1
(3)每次构造都选择两个树作为新的结点,因此不存在度为1的结点,只有度为0和2的结点
21、散列表的性质,k如何取值
散列函数可能会把两个或两个以上的不同关键字映射到同一地址,称这种情况为冲突,这些发生冲突的不同关键字称为同义词,这些冲突不可避免。
散列函数的构造
(1)散列函数定义域必须包括需要存储的关键字,值域的范围
(2)散列函数计算出来的地址应该能等概率、均匀的分布在整个地址空间,从而减少冲突

常见的散列函数:
(1)直接定址法:适合关键字分布基本连续的情况
(2)除留余数法:散列表的长度为m,取一个不大于m但接近或等于m的质数
(3)数字分析法
(4)平方折中法

处理冲突的方法
(1)开放地址法
1)线形探测
平均查找长度
ASL成功 =(比较次数*关键字个数)/总关键字个数
ASL失败 =(查找失败次数 * 关键字个数)/p的查找个数,地址的范围为p的取值范围

2)平方探测
3)在散列法

4)伪随即法
(2)拉链法
平均查找长度
ASL成功 =(关键字的位置*关键字的个数)/总关键字个数
ASL失败 =(查找失败次数 * 关键字个数)/p的查找个数(表长吗,答不是),地址的范围为p的取值范围
对于每一个同义词进行查找,

装填因子a=表中记录n/三列表长度m,
平均查找长度依赖于装填因子,不直接依赖于m和n,装填因子越大,表示记录越满,发生冲突可能性越大

在这里插入图片描述
https://blog.csdn.net/u011080472/article/details/51177412

在这里插入图片描述

22、各种排序的性质,时间复杂度,与初始序列是否有关
23、图的十字链表法、三元组、多重链表的画法
邻接表
以某个结点为起点,每个结点依次指向与其相连的顶点

#typedef MaxVerterNum 100
typedef struct ArcNode//边表结点
{
    
		int adjvex;//邻接点域
		struct ArcNode *next;//指针域
}ArcNode;
typedef struct VNode//顶点表结点
{
    
		VertexType data;//数据域
		ArcNode *first;//边表头指针
}VNode,AdjList[MaxVertexNum];
typedef struct
{
    
		AdjList vertices;//邻接表
		int vexnum,arcnum;
}ALGraph;//图

邻接表特点
(1)若图G为无向图,需要的空间为O(V+2E),因为不区分方向,只要有相邻的边就表示出来,若G为有向图,需要空间为O(V+E)。
(2)给定一定的点,很容易找到所有的边,为O(n),但是要找到顶点之间是否存在边,邻接表为O(n^2)
(3)有向图的邻接矩阵,出度为邻接表的结点个数,求入度需要遍历整个表。无向图,为顶点的个数

十字链表法
弧结点:[tailvex][headvex][hlink][tlnik][infor]
taillvex:尾弧结点
headvex:头弧结点
hlink:指向头相同的下一条边
tlink:指向尾相同的下一条边
顶点结点:[data][firstin][firstout]
firstin:第一条入度边
firstout:第一条出度边
在这里插入图片描述

可以方便的求出度和入度信息,但是删除麻烦
邻接多重表
边表:[mark][ivex][ilink][jvex][info]
ilink:指向下一条依附于ivex的边,相同尾巴
jlink:指向下一条依附于顶点jvex的边,相同头
在这里插入图片描述

24、数据结构相关的基础概念
25、树和二叉树的区别、性质
26、二叉树的平衡调整
二叉树调整笔记

27、二叉线索树

中序线索化创建
1、如果左子树为空,建立前驱线索
2、如果pre不为空且pre的右孩子为NULL,建立前驱结点的后继线索
pre标记刚刚访问过的结点

void InTread(ThreadTree &p,ThreadTree &pre)
{
    
		if(p != NULL)
		{
    
				InThread(p->lchild,pre);
				if(p->lchild == NULL)
				{
    
						p->lchild = pre;
						p->ltag = 1;
				}
				else
				{
    
						p->ltag = 0;
				}
				if(pre != NULL && pre->rchild == NULL)
				{
    
							pre->rchild = p;
							pre->rtag=1;
					}
					else
					{
    
							p->rtag=0;
					}
					pre = p;
					InThread(p->rchild,pre);
		}
}
void preTread(ThreadTree &p,ThreadTree &pre)
{
    
		if(p != NULL)
		{
    
				if(p->lchild != NULL)
				{
    
						p->lchild = pre;
						p->ltag = 1;
				}
				else
				{
    
						p->ltag=0;
				}
				if(pre != NULL && pre->rchild == NULL)
				{
    
							pre->rchild=p;
							pre->rtag = 1
				}
				else
				{
    
							pre->ltag = 0;
				}
				pre = p;
				
		}
}
ThreadNode *FirstNode(ThreadNode *p)
{
    
		while(p->ltag == 0)
				p = p->lchild;
		return p;
}
ThreadNode *NextNode(ThreadNode )
{
    
		if(p->rtag == 0)//如果p右子树没有线索,则找右子树中的第一个结点就是他的后继
				return FistNode(p->rchild);
			else
				return p->child;
}
void Inorder(ThreadNode *T)
{
    
		for(ThreadNode *p = FistNode(T);p != NULL;p = NextNode(p))
				visit(p);
}
BDAEC
DBEACG

在这里插入图片描述
中序线索二叉树
1、查找p的前驱:查找左线索,若无左线索,结点的前驱是遍历左子树访问的最后一个结点
2、查找p的后继,查找右线索,若无右线索,结点的后继是遍历右子树访问的第一个结点。
29、树与二叉树、森林的转换
(1)树转二叉树
兄弟相连,留长子
1)加线,在所有兄弟结点之间加线
2)去线,树中的每个结点,只保留与它与第一个孩子结点的连线,删除与其他孩子结点之间的连线
3)层次调整
在这里插入图片描述

(2)森林转为二叉树
去掉全部右孩线,孤立二叉在还原
1)把每棵树转为二叉树
2)第一棵树不动,从第二棵树开始,依次把根结点作为前一棵二叉树的根结点的右孩子,连接起来
在这里插入图片描述

(3)二叉树转树
左孩右右连双亲,去掉原来右孩线
在这里插入图片描述
(4)森林转为二叉树
树变二叉根相连
在这里插入图片描述
二叉树、森林的转换

30、二叉排序树的删除
(1)若被删除的结点z是叶子结点,则直接删除
(2)若被删除的结点z只有一颗左子树或者右子树,则让z的子树称为z父结点的子树,代替z的位置
(3)若被删除的结点z有左右两棵子树,则令z的直接后继代替z,然后从二叉排序树中删除这个直接后继或者直接前驱,变成了第一二情况
在这里插入图片描述
31、二叉排序树平均查找长度
二叉排序树查找效率取决于树的高度,若二叉排序树为平衡二叉树则高度为O(log2n),若为单只树(变成了链表)则为O(n)

二叉排序树生成树不唯一,当序列不同时树不同,二分查找的树唯一
32、图的边、顶点、度
简单路径:路径中,顶点不重复出现的路径称为简单路径。
简单回路:除第一个顶点和最后一个顶点外,其余顶点不重复出现的回路称为简单回路。
完全图,无向图有n(n-1)/2条边,任意两个顶点之间都存在边,有向图有n(n-1)条边,任意两个顶点之间都存在方向相反的弧
无向图,n个顶点有n-1条边,构成一个完全图,则为最小连通图,若多余n-1则为回路
有向图,n个顶点至少n条边,构成一个环路

若一个图有n个顶点,并且有大于n-1条边,则一定有环
33、BFS相关
BFS类似树的层序遍历
生成树不唯一
采用邻接表存储,每个顶点均被搜索入队一次,时间复杂度为O(V),在搜索邻接顶点时每条边至少被访问一次,时间复杂度为O(E),总的时间复杂度为O(V+E)
采用邻接矩阵存储,查找每个顶点的邻接点需要O(V),故需要O(V^2)

bool BFSTraverse(Graph G)
{
    
		for(i = 0;i < G.vexnum;++i)
		{
    
				visited[i] = False;
		}
		InitQueue(Q);
		for(i = 0;i < G.vexnum;++i)
		{
    
				if(!visited[i])
				{
    
						BFS(G,i);
				}
		}
}
void BFS(Graph G,int v)
{
    
		visit(v);//访问v
		visited[v] = True;//数组置为1
		EnQueue(Q,v);//入队列
		while(!IsEmpty(Q))//如果队列不空
		{
    
				DeQueue(Q,v);//出队列
				for(w = FirstNeighbor(G,v);w >= 0;w = NextNeighbor(G,v,w))//查找v相邻的边
				{
    
							if(!visited[i])//如果不空
							{
    
									visit(w);//访问
									visited[w] = True;
									EnQueue(Q,w);//入队
							}
				}
		}
}
//BFS求单源最短路径
void BFS_MIN_Distance(Graph G,int u)
{
    
		for(i = 0;i < G.vexnum;++i)
		{
    
				d[i] = #;
		}
		EnQueue(Q,u);
		while(!Isempty(Q))
		{
    
				DeQueue(Q,u);
				for(w = FirstNeighbor(G,u);w >= 0;w = NextNeighbor(G,u,w))
				{
    
						if(!visited[w])
						{
    
								visited[w] = True;
								d[w] = d[u]+1;//如果有路径则+1
								EnQueue(Q,w);
						}
				}
		}
}

33、DFS
DFS类似于树的先序遍历
DFS生成树和生成森林不唯一

void BFSTravers(Graph G)
{
    
		for(v = 0;v < G.vexnum;++v)
		{
    
				visit[v] = FAlse;
		}
		for(v = 0;v < G.vexnum;++v)
		{
    
				if(!visited[v])
						DFS((G,v);
		}
}
void DFS(Graph G,int v)
{
    
		visit(v);
		visited[v] = True;
		for(w = FirstNeighbor(G,v);w >= 0;w = NextNeighbor(G,v,w))
		{
    
				if(!visited[w])
				(
						DFS(G,w);
				)
		}
}
void DFS1(Graph G,int v)
{
    
		InitStack(S);
		visit(v);
		visited[v] = True;
		push(S,v);
		while(!IsEmpty(S))
		{
    
					pop(S,v);//出栈以后访问
					visit(v);
					for(w = FirstNeighbor(G,v);w >= 0;w = Neighbor(G,v,w))
					{
    
						if(!visited[w])
						{
    
								push(S,w);
								visited[w] = True;//每次进栈都要置为1
							}
					}
		}
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/threestooegs/article/details/121204289

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法