Acm9-二分查找和拓排

Acm 9:

 <1>重点:拓扑排序、二分查找

 1).拓扑排序

 原理:使用栈的原理,即采用dsf的方法,找到度为0的点,将其入栈,通过while循环实现对下一个点的查找;同时弹出顶,寻找与弹出点有关的点->目的删除边;

i=mystack.top();

mystack.pop();

cout<<k<<” ”;

for(p=adj[i].next;p!=NULL;p=p->next)

       {

           int k=p->adjvex;

           indegree[k]--;

           if(indegree[k]==0)

                mystack.push(k);

       }

目的:对一串数字进行有序的排序;

例:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<stack>
#include<memory.h>
 
using namespace std;
#define MAX 9999
 
stack<int>mystack;
int indegree[MAX];
 
struct node
{
   int adjvex;
   node* next;
}adj[MAX];
 
int Create(node adj[],int n,int m)//邻接表建表函数,n代表定点数,m代表边数
{
   int i;
   node *p;
   for(i=1;i<=n;i++)
    {
       
       adj[i].adjvex=i;
       adj[i].next=NULL;
    }
   for(i=1;i<=m;i++)
    {
       cout<<"请输入第"<<i<<"条边:";
       int u,v;
       cin>>u>>v;
       p=new node;
       p->adjvex=v;
       p->next=adj[u].next;
       adj[u].next=p;
    }
   return 1;
}
 
 
void print(int n)//邻接表打印函数
{
   int i;
   node *p;
   for(i=1;i<=n;i++)
    {
       p=&adj[i];
       while(p!=NULL)
       {
           cout<<p->adjvex<<' ';
           p=p->next;
       }
       cout<<endl;
    }
}
 
void topsort(node adj[],int n)
{
 
   int i;
    node *p;
   memset(indegree,0,sizeof(indegree));
   for(i=1;i<=n;i++)
    {
 
       p=adj[i].next;
       while(p!=NULL)
       {
           indegree[p->adjvex]++;
           p=p->next;
       }
    }
   for(i=1;i<=n;i++)
    {
 
       if(indegree[i]==0)
           mystack.push(i);
    }
   int count=0;
   while(mystack.size()!=0)
    {
 
       i=mystack.top();
       mystack.pop();
       cout<<i<<' ';
       count++;
       for(p=adj[i].next;p!=NULL;p=p->next)
       {
           int k=p->adjvex;
           indegree[k]--;
           if(indegree[k]==0)
                mystack.push(k);
       }
    }
   cout<<endl;
   if(count<n)cout<<"有回路"<<endl;
}
 
int main()
{
   int n;
   int m;
   cout<<"请输入顶点数及边数:";
   cin>>n>>m;
   Create(adj,n,m);
   cout<<"输入的邻接表为:"<<endl;
   print(n);
   cout<<"拓扑排序结果为:"<<endl;
   topsort(adj,n);
   system("pause");
   return 0;
}


注意点:

a.p=&adj[i]结构指针指向结构体;注意写法;

b. for(i=1;i<=n;i++)

    {

       

       adj[i].adjvex=i;

       adj[i].next=NULL;

    }

目的建立表头

 for(i=1;i<=m;i++)

    {

       cout<<"请输入第"<<i<<"条边:";

       int u,v;

       cin>>u>>v;

       p=new node;

       p->adjvex=v;

       p->next=adj[u].next;

       adj[u].next=p;

    }

在建立有表头的基础之上,通过地址的指向关系来建立彼此的联系

c. for(i=1;i<=n;i++)

    {

 

       if(indegree[i]==0)

           mystack.push(i);

    }

将度为0的点入栈

<2>二分法查找

原理: 

先确定左右边的范围,然后找到中点,比较中间值与目标值的关系,进一步确定左右边的范围,然后重复以上过程,直到查找到为止;

代码:

in a[9]={0,1,2,3,4,9,10,16,78}

int binary(int n)

{

 int r,l,mid;

 r=1;

 l=8;

 mid=(r+l)/2;

 while(r<l)

{

 

 if(a[mid]>n)

{

 r=mid-1;

}

else

l=mid+1;

mid=(r+l)/2;

}

return l;//表示目标数的下标;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值