Linux与数据结构 2019-3-30下午

1.图

1.1 图的广度遍历BFS

  • 1.首先我们考虑,任选一个顶点v1,从给定的顶点v1开始在邻接矩阵中找跟其相关的顶点,存入辅助队列中;
void BFS(Graph* p_graph, int begin_vertex)
{
	if(p_graph == NULL)return;

	// 申请辅助队列
	Queue* p_queue = NULL;
	q_Init(&p_queue);

	// 定义标记数组
	int *p_flag = NULL;
	p_flag = (int*)malloc(sizeof(int)*p_graph->n_count);
	memset(p_flag, 0, sizeof(int)*p_graph->n_count)

	q_Push(p_queue, begin_vertex);
	p_flag[begin_vertex-1] = 1;
	while(p_queue->nCount != 0)
	{
		begin_vertex = q_Pop(p_queue);
		printf("%d ", begin_vertex);
		int i;
		for(i=0; i<p_graph->n_vertex; i++)
		{
			if(p_graph->p_matrix[(begin_vertex-1)*p_graph->n_vertex+i] == 1 || p_flag[i] == 0)
			{
				q_Push(p_queue, i+1);
				p_flag[i] = 1;
			}
		}
	}
}

2.求最短路径

2.1 迪杰斯特拉算法

  • 1.时间复杂度为 O(N^2) ;
  • 2.是一种贪心算法,求解有向带边权图的最短路问题,给定起点,给定边权,求到达每一个点的最短距离;
  • 3.步骤(起始顶点为v1):
    • 1.从v1开始,到自己的长度为无穷(用0表示),到其他顶点的路径可以根据图得到,可以列出一个以v1为行向量,其余顶点为列的一维数组,长度为顶点的个数;
    • 2.在上述的一维数组中找出最小的值所对应的顶点v2(比方说,并不一定就是v2),以v1 v2为新的顶点,列出一个新的数组(数组中与v1和v2的值仍为之前的),再在新数组中找出距离最小的顶点v3;
    • 3.依次重复上述步骤;

2.2 克鲁斯卡尔算法

  • 1.基于克鲁斯卡尔算法的最小生成树
    • 1.用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。
  • 2.步骤:
    • 1.将图中的所有边都去掉;
    • 2.在所有的边中找权值最小的边加到图中;
    • 3.找次小的边加入图中;
    • 4.再找次次小的边加入图中,若构成回路则放弃该边,重新找剩余的边中最小的;
    • 5.重复4。

2.3 普里姆算法

  • 1.可在加权连通图里搜索最小生成树;
  • 2.步骤:
    • 1.初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {},为空;
    • 2.重复下列操作,直到Vnew = V:
    • 3.在集合E中选取权值最小的边<u, v>,其中u为集合Vnew中的元素,而v不在Vnew集合当中,并且v∈V(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
    • 4.将v加入集合Vnew中,将<u, v>边加入集合Enew中;
    • 5.输出:使用集合Vnew和Enew来描述所得到的最小生成树。

3.课堂随测

3.1 如何判定一颗给定的二叉树是对称二叉树?

  • 1.首先若树为空,也是一个对称的;
  • 2.若左孩子为空,右孩子不为空,返回0;
  • 3.若右孩子为空,左孩子不为空,返回0;
  • 4.若左孩子和右孩子都为空,则返回1;
  • 5.对左孩子的左和右孩子的右以及左孩子的右和右孩子的左进行2-5步操作;
int ChildIsSymme(BinaryTree* p_left, BinaryTree* p_right)
{
	if(p_left != NULL && p_right == NULL)return 0;
	if(p_left == NULL && p_right != NULL)return 0;
	if(p_left == NULL && p_right == NULL)return 1;
	if(p_left != NULL && p_right != NULL && p_right->n_value == p_left->n_value)
		return ChildIsSymme(p_left->p_left, p_right->p_right)&&ChildIsSymme(p_left->p_right, p_right->p_left);
}

int IsSymme(BinaryTree* p_tree)
{
	if(p_tree == NULL)return 1;

	return ChildIsSymme(p_tree->p_left, p_tree->p_right);
}

3.2 如何判断一个整数的二进制中“1”的个数?

  • 1.首先用这个整数num与1进行位于;
  • 2.其次将这个整数num右移1位;
int CountOne(int num)
{
	int count = 0;
	while(num)
	{
		if(num & 1)
			count++;
		num = num >> 1;
	}

	return count;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值