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;
}