1.最短路径问题、
(权重,不同的问法)(抽象,在网络中,求两个不同顶点之间的所有路径中,便的权值之和最小的那一条路径)
分类:单源最短路径问题 多源最短路径问题
2.无权图的单元最短路算法
1.按递增的顺序找出各个顶点的最短路
(广度优先搜索)
void BFS (Vertex S)
{
visited [S]=ture;
Enqueue(S,Q);
while(!IsEmpty(Q)){
V=Dequeue(Q)
for(V 的每个邻接点W)
if(!visited[W] )
visited[W]=ture;
Enqueue(WW,Q);
}
}
3.无权图的单元最短路算法
void Unweighted (Vertex S)
{
Enqueue(S,Q);
while(!IsEmpty(Q)){
V=Dequeue(Q)
for(V 的每个邻接点W)
if(dist[w]==-1){
dist[w]=dist[v]+1;
path[w]=V
Enqueue(WW,Q);
}
}
}
4.有权图的最短路径
//按照递增的顺序
//Dijkstra算法
//令S= 源点s+已经确定的最短路径的顶点v
void Dijkstra(Vertex s)
{while(1){
V=未收录顶点中dist最小者;
if(这样的v不存在)
break;
collected [V]=true;
for(V 的每个邻接点w)
if(dist[v]+E<v,w> < dist[w])
{
dist[w]=dist[v]+E<v,w>;
path[w]=V;
}
}
}
5.多源最短路径
//方法1 直接将单元算法 调用V遍
//方法二 Floyd 算法
void Fioyd()
{
for(i=0;i<N,i++)
for(j=0;j<N,j++){
D[i,j]=G[i][j];
}
for(k=0;k<N,k++)
for(i=0;i<N;j++)
if(D[i][k]+D[k][j]<D[i][j]){
D[i][j]=D[i][k]+D[k][j];
path[i][j]=k;
}
}
Prim算法--让一棵小树长大
//最小生成树
//一棵树 (无回路) 生成树(包含全部顶点) (边的权重和最小)
// 最小生成树<--->图连通
6.贪心算法
(注意:只能用图里的边,只能正好用掉v-1条边 ,不能右回路)
void Dijkstra(Vertex s)
{while(1){
V=未收录顶点中dist最小者;
if(这样的v不存在)
break;
collected [V]=true;
for(V 的每个邻接点w)
if(dist[v]+E<v,w> < dist[w])
{
dist[w]=dist[v]+E<v,w>;
path[w]=V;
}
}
}
void Prim()
{ NST ={s};
while(1){
v=未收录顶点中dist最小值;
if(这样的v不存在)
break;
将v收录进MST:dist[v]=0;
for(v的每个邻接点w)
if(dist[w]!=0)
if (E<v,w> < dist[w]){
dist[w]=E<v,w>;
parent[w]=v;
}
}
if(MST中收的顶点不到|v|个)
Error("生成树不存在") ;
}
7.Kruskal算法
void Krusal (Graph G)
{
MST={};
while {
从E中去一条权重最小的边E<v,w>;//最小堆
将E<v,w>从E中删除;
if(将E<v,w>不在MST中构成回路 );//并查集
将E<v,w>加入MST中;
else
彻底无视 E<v,w>;
}
if (MST中不到|v|-1条边)
Error("生成树不存在";)
}
拓扑排序
// 如果图中从v到w有一条有向路径,则v一定排在w之前,满足此条件的顶点序列称为一个拓扑序
//有向无环图
void Top Sort()
{
for(cnt=0;cnt<|v|;cnt++){
V=未输出的长度为0的顶点;
if(这样的v不存在)(
Error ("图中有回路");
break;
)
输出v,或者记录v的输出序号;
for(V的每个邻接点w);
Indegree[w]--;
}
}
//聪明的算法(
随时将入度变成0的顶点放在一个容器里
void Top Sort()
{
for (图中的每个顶点V)
if (Indegree[V]==0)
Enqueue (V,Q);
while (!IsEmpty(Q)){
V=Dequeue(Q);
输出V,或者记录v的输出编号; cnt++;
for(V的每个邻接点w)
if(--Indegree[w]==0)
Enqueue(W,Q);
}
if (cnt !=|V| )
Error(""图中有回路");
}
//算法,排序 查找
//前提
//函数头 void X_Sort (ElementType A [] ,int N ) N是正整数
//基于比较的排序 只讨论内部排序
//稳定性 任意两个相等的数据,排序前后的相对位置不发生改变
8.简单排序-----冒泡排序
最大的一定在最后一个(第一次排序 )
void Bubble_sort (ElementType A[] ,int N)
{
for (P=N-1;P>=0;P--){
flag=0;
if ( A[i]>A[i+1];{
Swap( A[i], A[i+1]);
flag=1;
}
)
if (flag==0) break;
}
}
//最好情况:T = O(N) (顺序
//最坏情况;T = O(N) 平方 (逆序
9.插入排序
void Insertion_Sort (ElementType A[],int N)
{
for(P=1;P<N;P++)
Tmp=A[P];
for (i=P;i>0&&A[i-1]>Tmp;i--)
A[i]=A[i-1];
A[i]=Tmp;
}
//时间复杂度下界
//定理:任意N个不同的元素组成的序列平均具有
//更多增量序列 Hibbard增量序列 Sedge wick增量序列
10.选择排序
void Selection——Sort(ElementType A[],int N )
{
for (i=0;i<N;i++){
MinPostion=ScanForMin(A,i,N-1);
Swap(A[i],A[MinPoistion]);
}
}
11.堆排序
//算法1
void Heap_Sort (ElementType A[],int N)
{
BuildHeap(A);
for(i=0;i<N,i++)
TmpA[i]=DeleteMin(A);
for( i=0;i<N;i++);
A[i] =TmpA[i];
}
//时间复杂度 T(N)=O(N logN)
//算法二
void Heap_Sort (ElementType A[],int N)
{
for(i=N/2;i>=0;i--)
PercDown(A,i,N);
for (i=N-1;i>0;i--){
Swap( &A[0],&A[i]);
PercDown(A,0,i);
}
}
//定理;堆排序处理N个不同元素的随机排列的平均比较次数是 2NlogN-O(Nlog logN)
12.归并排序
//核心:有序子列的归并
void Merge(ElementType A[],ElementType TmpA[],
int L,int R,int RightEnd)
{
LeftEnd=R-1;
Tmp=L;
NumElements=RightEnd-L+1;
while( L<=LeftEnd&&R<=RightEnd){
if(A[L]<=A[R]) TmpA[Tmp++]=A[L++];
else TmpA[Tmp++]=A[R++];
}
while(L<=LeftEnd)
TmpA[Tmp++]=A[L++];
while( R<=RightEnd)
TmpA[Tmp++]=A[L++];
for(i=0;i<NumElements;i++;RightEnd--)
A[RightEnd]=TmpA[RightEnd];
}
//统一函数接口
void Merge_sort(ElementType A[],int N)
{
ElementType *TmpA;
TmpA=malloc(N*sizeof(ElementType));
if (TmpA!=NULL){
MSort(A,TmpA,O,N-1);
free(TmpA);
}
else Error("空间不足");
}
void Merge_pass(ElementType A[],ElementType TmpA[],int N,int length)
{for(i=0;i<=N-2*length;i+=2*length)
Mergel(A,TmpA,i,i+length,i+2*length-1);
if(i+length<N)
Mergel(A,TmpA,i,i+length,N-1);
else
for(j=i;j<N;j++)TmpA[j]=A[j];
}
void Merge_sort(ElementType A[],int N)
{
int length=1;
ElementType *TmpA ;
TmpA=malloc(N*sizeof(ElementType));
if (TmpA!=NULL){
while(length<N ){
Mergel_pass(A,TmpA,N, length);
length *=2;
Merge_pass(TmpA,A,N,length);
length *=2;
}
free(TmpA);
}
else Error("空间不足");
}
//非递归算法
void Merge_pass(ElementType A[],ElementTypeA[],int N,int,length)
{
for(i=0;i<=N-2*length;i+=2*length)
Merge(A,TmpA,i,i+length,i+2*length-1);
if(i+length<N)
Merge(A,TmpA,i,i+length,N-1);
else
for(j=i;j<N;j++) TmpA[j]=A[j];
}
void Merge_sort(ElementType A[],int N)
{
int length=1;
ElementType *TmpA;
TmpA=malloc(N * sizeof(ElementType));
if(Tmp !=NULL){
while(){
Merge_pass(A,TmpA,N,length);
length *=2;
Merge_pass(TmpA,A,N,length);
length *=2;
}
free(TmpA);
}
else Error("空间不足");
}
13.快速排序
void Quichsort(ElementType A[],int N)
{
if(N<2) return;
pivot=从A[]中任意选一个主元;
将S={A[]\pivot}分成2个独立子集;
A1={a(属于)S|a<=pivot}和
A2={a(属于)S|a>=pivot} ;
A[]=Quicksort(A1,N1)
(povit)
Quichsort(A2,N2);
}
//选主元
ElementType Median3(ElementType A[],int Left,int Right0
{
int Center =(Left+Right)/2;
if(A[Left]>A[Center])
Swap(&A[Left],&A[Center]);
if(A[Left]>A[Right])
Swap(&A[Left],&A[Right]);
if(A[Center]>A[Right])
Swap(&A[Center],&A[Right]);
Swap(&A[Center],&A[Right-1]);
return ;
}