首页 > 编程语言 > 详细

树、图、排序查找重要算法(960算法)

时间:2019-09-15 20:33:23      阅读:222      评论:0      收藏:0      [点我收藏+]
  1. 设计求T的WPL的算法:

  (1).给出二叉树结点的数据类型定义;

  (2).给出C语言描述算法;

  【1】:

typedef struct node

        { int weight;

         struct node *left,*right;  //指向结点左右子女的指针

         }BiNode,*BiTree;

  【2】:

int WPL=0;

      void inorder(BiTree bt,level lv)

      //bt是二叉树,lv是结点的层次,初值为1

           { if(bt)

               {inorder (bt->left,lv+1);   //中序遍历左子树

                if(bt->left==null &&bt->right==null)   //判断该结点是否为叶子

                     WPL+=(lv-1)*bt->weight;      //累加结点带权路径长度

                 inorder(bt->right,lv+1);

              }

          }

【先序遍历】NLR(递归)

void PreOrder(BiTree T){

if(T!=NULL){

    visit(T);     //访问根结点

    PreOrder(T->lchild);   //递归遍历左子树

    preOrder(T->rchild);

}

 }

【中序遍历】LNR(递归)

void InOrder(BiTree T){

if(T!=NULL){

InOrder(T->lchild);

visit(T);

InOrder(T->rchild);

}

 }

【后序遍历】LRN(递归)

 

void PostOrder(BiTree T){

if(T!=NULL){

PostOrder(T->lchild);

PostOrder(T->rchild);

visit(T);

}

}

 

【先序非递归遍历】

void PreOrderTraverse(BiTree b){

InitStack(S);

BiTree p=b;   //工作指针p

while(p||!IsEmpty(S)){

   while(p){

       Printf(“%c”,p->data);  //先序先遍历结点

       Push(S,p);    //进栈保存

       p=p->lchild;

       }

       if(!IsEmpty(S)){

           p=Pop(S);

           p=p->rchild;

       }

    }

}

【中序非递归遍历】

void InOrder(BiTree b){

InitStack(S);

BiTree p=b;

while(p||!IsEmpty(S)){   //栈不空或P不空时循环

    if(p){             //根指针进栈,遍历左子树

       Push(S,p);      //每遇到非空二叉树先向左走

       p=p->lchild;

     }

     else{             //根指针退栈,访问根结点,遍历右子树

        Pop(S,p);

        visit(b);

        p=p->rchild;    //再向右子树走

     }

  }

   }

【后序非递归遍历】

 1 void PostOrder(BiTree b){
 2 
 3 InitStack(S);
 4 
 5 BiTree p=b,r=NULL;   //工作指针P,辅助指针r
 6 
 7 while(p||!IsEmpty(S)){
 8 
 9 //1.从根结点到最左下角的左子树都入栈
10 
11 if(p){
12 
13     Push(S,p);
14 
15     p=p->lchild;
16 
17     }
18 
19 //2.返回栈顶的两种情况
20 
21 else{
22 
23     GetTop(S,p);    //取栈顶,不是出栈!
24 
25     //1)右子树还未访问,而且右子树不空,第一次栈顶
26 
27     if(p->rchild&&p->rchild!=r)
28 
29       p=p->rchild;
30 
31     //2)右子树已经访问或为空,接下来出栈访问结点
32 
33  else{
34 
35      Pop(S,p);
36 
37      Printf(“%c”,p->data);
38 
39      r=p;  //指向访问过的右子树根结点
40 
41      p=NULL;   //使p为空从而继续访问栈顶
42 
43      }
44 
45 }

【层次遍历】

void LevelOrder(BiTree T){

InitQueue(Q);

BiTree p;

EnQueue(Q,T);      //将根结点入队

while(!IsEmpty(Q)){   //队列不空循环

     DeQueue(Q,P);     //对头元素出队

     visit(p);

     if(p->lchild!=NULL)

       EnQueue(Q,p->lchild);   //左子树不空,则左子树入队列

     if(p->rchild!=NULL)

       EnQueue(Q,p->rchild);   //右子树不空,则右子树入队列

}

设计一个算法,从大到小输出二叉排序树中所有其值不小于k 的关键字。

【分析】:

        为了从大到小输出,先遍历右子树,再访问根结点,后遍历左子树。

【算法】:

void OutPut(BSTNode *bt,KeyType k){

if(bt==NULL)

   return ;

if(bt->rchild!=NULL)

    OutPut(bt->rchild,k);    //递归输出右子树结点

if(bt->data>=k)

    Printf(“%d”,bt->data);    //只输出大于等于k的结点值

if(bt->lchild!=NULL)

    OutPut(bt->lchild,k);      //递归输出左子树的结点

}

【图的邻接矩阵存储结构定义】

#define MaxVertexNum 100       //顶点数目的最大值

typedef char VertextType;        //顶点的数据类型

typedef int EdgeType;           //带权图中边上权值的数据类型

typedef struct{

     VertexType Vex[MaxVertexNum];  //顶点表

     EdgeType Edge[MaxVertexNum][MaxVertexNum];  //邻接矩阵,边表

     int vexnum,arcnum;            //图的当前顶点数和弧数

}MGraph;

【图的邻接表存储结构定义】

#define MaxVertexNum 100      //图中顶点数目的最大值

typedef struct ArcNode{         //边表结点

     int adjvex;            //该弧所指向的顶点的位置

     struct ArcNode *next;    //指向下一条弧的指针

     //InfoType info;        //网的边权值

}ArcNode;

typedef struct VNode{       //顶点表结点

      VertextType data;      //顶点信息

      ArcNode *first;       //指向第一条依附该顶点的弧的指针

}VNode,AdjList[MaxVertexNum];

typedef struct{

      AdjList vertices;     //邻接表

      int vexnum,arcnum;   //图的顶点数和弧数

}ALGraph;        //ALGraph是以邻接表存储的图类型

图的遍历:

BFS算法】:

 1 #define MaxSize 100;
 2 
 3 bool visited[MaxSize];     //访问标记数组
 4 
 5 void BFS(Graph G,int v){
 6 
 7      ArcNode *p;
 8 
 9      InitQueue(Q);
10 
11      visit(v);
12 
13      visited[v]=TRUE;     //对v做已访问标记
14 
15      Enqueue(Q,v);
16 
17      while(!IsEmpty(Q)){
18 
19         DeQueue(Q,v);
20 
21         p=G->adjList[v].firstedge;    //指针P指向当前顶点的边表链表头指针
22 
23      while(p){
24 
25             if(!visited[p->adjvex]){   //P所指向顶点如果未被访问
26 
27             visit(p->adjvex);
28 
29             visited[p->adjvex]=TRUE;
30 
31             EnQueue(Q,p->adjvex);    //这个顶点入队列
32 
33             }
34 
35             p=p->next;      //p指向该顶点的下一条边
36 
37       }
38 
39 }
40 
41   }
42 
43 void BFSTraverse(Graph G){
44 
45      for(i=0;i<G.vexnum;i++)
46 
47      visited[i]=FALSE;       //访问标记数组初始化       
48 
49      for(i=0;i<G.vexnum;i++){    //从0号顶点开始遍历
50 
51            if(!visited[i])        //对每个连通分量调用一次BFS
52 
53               BFS(G,i);f        //vi未访问过,从vi开始BFS
54 
55 }
56 
57 }

BFS算法求解单源最短路径问题】

void BFS_MIN_Distance(Graph G,int u){

//d[i]表示从u到i结点的最短路径

     for(i=0;i<G.vexnum;++i)

        d[i]=65535;            //初始化路径长度

     visited[u]=TRUE; d[u]=0;

     EnQueue(Q,u);

     while(!IsEmpty(Q)){        //BFS算法主过程

         DeQueue(Q,u);        //对头元素u出队

         for(w=FirstNeighbor(G,u);w>=0;w=NextNeighbor(G,u,w))

            if(!visited[w]){      //w为u的尚未访问的邻接顶点

               visited[w]=TRUE;   //设已访问标记

              d[w]=d[u]+1;     //路径长度加1

              EnQueue(Q,w);    //顶点w入队

            }//if

      }//while

}

【DFS算法】(递归)

 1 #define MaxSize 100;
 2 
 3 bool visited[MaxSize];
 4 
 5 void DFS(Graph G,int v){
 6 
 7 ArcNode *p;
 8 
 9 visit(v);
10 
11 visited[v]=TRUE;  //设已访问标记
12 
13 p=G->adjList[v].firstarc;
14 
15 while(p!=NULL){     //没遍历完顶点的所有邻接顶点
16 
17      if(!visited[p->adjvex]){  //如果该顶点没被访问
18 
19        DFS(G,p->adjvex);    //递归访问该顶点
20 
21      }
22 
23      p=p->nextarc;  //看还有没有其他未访问的顶点
24 
25  }
26 
27 }
28 
29 void DFSTraverse(Graph G){
30 
31 int i;
32 
33 for(i=0;i<G->vexnum;i++)
34 
35   visited[i]=false;
36 
37 for(i=0;i<G->vexnum;i++)
38 
39    if(!visited[i])
40 
41    DFS(G,i);
42 
43 }

(非递归)邻接表存储

DFS非递归算法】:

void DFS_Non_RC(AGraph &G,int v){

//从顶点v开始进行深度优先搜索,一次遍历一个连通分量的所有顶点

int w;     //顶点序号

InitStack(S);

for(i=0;i<G.vexnum;i++)

   visited[i]=FALSE;      //初始化visited

   Push(S,v); visited[v]=TRUE;    //v入栈并置visited[v]

while(!IsEmpty(S)){

   k=Pop(S);         //栈中退出一个顶点

   visit(v);         //先访问,再将其子结点入栈

   for(w=FirstNeighbor(G,k);w>=0;w=NextNeighbor(G,k,w))

                      //k所有邻接点

        if(!visited[w]){     //未进过栈的顶点进栈

            Push(S,w);

            visited[w]=true;     //作标记,以免再次入栈

         }//if

     }//while

 }

【拓扑排序算法】:

 1 bool TopologicalSort(Graph G){
 2 
 3 //如果G存在拓扑排序,返回truel;否则返回false,这时G中存在环
 4 
 5 InitStack(S);
 6 
 7 for(int i=0;i<G.vexnum;i++)
 8 
 9     if(indegree[i]==0)
10 
11         Push(S,i);      //将所有入度为0的顶点进栈
12 
13 int count=0;      //计数,记录当前已经输出的顶点数
14 
15 while(!IsEmpty(S)){     //栈不空,则存在入度为0的顶点
16 
17      Pop(S,i);       //栈顶元素出栈
18 
19      print[count++]=i;     //输出顶点i
20 
21      for(p=G.vertices[i].firstarc;p;p=p->nextarc){
22 
23      //将所有i指向的顶点的入度减1,并且将入度减为0的顶点压入栈S
24 
25          v=p->adjvex;
26 
27          if(!(- -indegree[v]))
28 
29               Push(S,v);       //入度为0,则入栈
30 
31       }//for
32 
33 }//while
34 
35 if(count<G.vexnum)
36 
37     return false;     //排序失败,有向图中有回路
38 
39 else
40 
41     return true;    //成功
42 
43 }

【直接插入排序算法】

void InsertSort(ElemType A[],int n){

int i,j;

for(i=2;i<=n;i++)      //依次将A[2]~A[n]插入到前面已排序序列

if(A[i].key<A[i-1].key){ //若A[i]的关键码小于其前驱,需将A[i]插入有序表

          A[0]=A[i];     //复制为哨兵,A[0]不存放元素

          for(j=i-1;A[0].key<A[j].key;--j)  //从后往前查找待插入位置

               A[j+1]=A[j];   //向后挪位

          A[j+1]=A[0];     //复制到插入位置

      }

   }

【冒泡排序算法】:

void BubbleSort(ElemType A[],int n){

//将序列A中的元素按从小到大排序

   for(i=0;i<n-1;i++){

      flag=false;    //表示本趟冒泡是否发生交换的标志

      for(j=n-1;j>i;j--)   //一趟冒泡过程

          if(A[j-1].key>A[j].key){  //若为逆序

              swap(A[j-1],A[j]);

              flag=true;

          }

       if(flag==false)

            return ;       //本趟遍历后没有发生交换,说明表已经有序

}

}

【折半查找】:

int Binary_Search(SeqList L,ElemType key){

//在有序表L中查找关键字为key的元素,若存在返回其位置,

     int low=0,high=L.TableLen-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;

}

树、图、排序查找重要算法(960算法)

原文:https://www.cnblogs.com/itzine/p/11523979.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!