数据结构(3)

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("生成树不存在";) 
 } 
  1. 拓扑排序

// 如果图中从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 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值