数据结构之图及算法

一 图 

 

描述一副图:顶点,边的关系

 

1.邻接矩阵存储

 

typedef struct 

{

 VTYPE v[N];

 int matrix[N][N];

}graph_t;

 

 

graph_t *create_empty_graph()

{

 graph_t *g;

 int i = 0;

 

 g = (graph_t *)malloc(sizeof(graph_t));

 memset(g,0,sizeof(graph_t));

 

 for(i = 0;i < N;i ++)

 {

  g->v[i] = i;

 }

 

 return g;

}

 

int input_graph_edge(graph_t *g)

{

 int i,j;

 

 //输入边的关系

 //(V0,V1) (V0,V2) ... a回车

 

 while(scanf("(V%d,V%d)",&i,&j) == 2)

 {

  getchar();//去掉空格

  g->matrix[i][j] = g->matrix[j][i] = 1;

 }

 

 //清缓存的非法字符

 while(getchar() != '\n');

 

 return 0;

}

 

//输出顶点,和链接矩阵

int printf_graph(graph_t *g)

 

 

必须掌握:

(1)链表相关算法

(2)栈和队列

(3)二叉树遍历[层次遍历]

(4)哈希表

(5)冒泡,选择,快排

 

图的邻接表存储:

 

typedef struct  vnode

{

 VTYPE v;

 struct vnode *next;

}LinkGraph;

 

#define N 5 

#define ADDR_LEN sizeof(int)

 

 

LinkGraph **create_graphlist()

{

 int i = 0;

 LinkGraph **g;

 

 g = (LinkGraph **)malloc(N * ADDR_LEN);

 for(i = 0;i < N;i ++)

 {

  g[i] = (LinkGraph *)malloc(sizeof(LinkGraph));

  g[i]->v = i;

 }

 

 return g;

}

 

 

int input_graphlist_edge(LinkGraph  **g)

{

 int i,j;

 

 //输入边的关系

 //<V0,V1> <V0,V2> ... a回车

 

 while(scanf("<V%d,V%d>",&i,&j) == 2)

 {

  getchar();//去掉空格

  insert_order_linklist(g[i],j);

 }

 

 //清缓存的非法字符

 while(getchar() != '\n');

 

 return 0;

}

 

int printf_graphlist(LinkGraph **g);

 

#include <stdio.h>

#include <stdlib.h>

 

typedef int VTYPE;

 

typedef struct  vnode

{

 VTYPE v;

 struct vnode *next;

}LinkGraph;

 

#define N 5 

#define ADDR_LEN sizeof(int)

 

LinkGraph **create_graphlist()

{

 int i = 0;

 LinkGraph **g;

 

 g = (LinkGraph **)malloc(N * ADDR_LEN);

 for(i = 0;i < N;i ++)

 {

  g[i] = (LinkGraph *)malloc(sizeof(LinkGraph));

  g[i]->v = i;

  g[i]->next = NULL;

 }

 

 return g;

}

 

int insert_order_linklist(LinkGraph *head,VTYPE v)

{

 LinkGraph *temp;

 LinkGraph *p,*q;

 

 q = head;

 p = head->next;

 

 //head 1   3  4

 //       2

 while(p != NULL)

 {

  if(p->v > v)

   break;

  else{

   p = p->next;

   q = q->next;

  }

 }

 

 temp = (LinkGraph *)malloc(sizeof(LinkGraph));

 temp->v = v;

 

 temp->next = p; //temp->next = q->next;

 q->next    = temp;

 return 0;

}

 

 

int input_graphlist_edge(LinkGraph  **g)

{

 int i,j;

 

 //输入边的关系

 //<V0,V1> <V0,V2> ... a回车

 

 while(scanf("<V%d,V%d>",&i,&j) == 2)

 {

  getchar();//去掉空格

  insert_order_linklist(g[i],j);

 }

 

 //清缓存的非法字符

 while(getchar() != '\n');

 

 return 0;

}

 

int printf_linklist(LinkGraph *head)

{

 LinkGraph *p = head;

 

 while(p != NULL)

 {

  printf("V%d ",p->v);

  p = p->next;

 }

 printf("\n");

 

 return 0;

}

 

int printf_graphlist(LinkGraph **g)

{

 int i = 0;

 

 for(i = 0;i < N;i ++)

 {

  printf_linklist(g[i]);

 }

 

 return 0;

}

 

int main(int argc, const char *argv[])

{

 LinkGraph **g = create_graphlist();

 input_graphlist_edge(g);

 

 printf_graphlist(g);

 return 0;

}

 

 

dijkstra

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

#define N 6

#define M (1 << 20)

 

int main()

{

 //邻接矩阵

 int matrix[N][N] = {

  {0,20,15,M,M,M},

  {2,0,4,M,10,30},

  {M,M,0,M,M,10},

  {M,M,M,0,M,M},

  {M,M,M,15,0,10},

  {M,M,M,4,M,0}

 };

 

 int i = 0;

 int start;//起始顶点

 int s[N] = {0};//最短路径是否求出的标志

 int dist[N];//记录最短路径的大小

 char *Path[N];//记录最短路径

 

 int min_path,//最短路径大小

  min_v;//到达的顶点

 

 char buf[5] = {0};

 int count = 0;

 

 //从V0到达其他定点

 start = 0;

 s[start] = 1;

 

 //初始化,dist,path

 for(i = 0;i < N;i ++)

 {

  dist[i] = matrix[start][i];

 

  Path[i] = (char *)malloc(N * sizeof(char) * 2);

 

  //V0

  //printf("V%d",start);

  sprintf(Path[i],"V%d",start);

 }

 

 while(count < N-1)

 {

  min_path = M;

 

  //找最短距离

  for(i = 0;i < N;i ++)

  {

   if(s[i] == 0 && min_path > dist[i])

   {

    min_path = dist[i];

    min_v = i;

   }

  }

 

  s[min_v] = 1;

  sprintf(buf,"V%d",min_v);//buf:V2

  strcat(Path[min_v],buf);//Path[2]:V0  : V0 V2

 

  //更新dist[N]的值

  for(i = 0;i < N;i ++)

  {

   //path(<start,i>) > path(<start,min_v>) + path(<min_v,i>)

   if(s[i] == 0 && dist[i] > dist[min_v] + matrix[min_v][i])

   {

    dist[i] = dist[min_v] + matrix[min_v][i];

    strcpy(Path[i],Path[min_v]);

   }

  }

 

  count ++;

 }

 

 for(i = 0;i < N;i ++)

 {

  printf("V%d -> V%d\t%d\t%s\n",start,i,dist[i],Path[i]);

 }

 

 return 0;

}

 

#include <stdio.h>

 

int main(int argc, const char *argv[])

{

 int data = 100;

 char buf[100];

 

 printf("data = %d\n",data);

 sprintf(buf,"data = %d\n",data);

 

 printf("buf : %s\n",buf);

 

 return 0;

}

 

hash

 

#include <stdio.h>

#include <stdlib.h>

 

typedef int DATATYPE;

 

typedef struct node 

{

 DATATYPE data;

 struct node *next;

}LinkNode;

 

LinkNode *addr[13];

 

int insert_hash_table(int data)

{

 int index;

 LinkNode  **p;

 LinkNode *temp;

 

 index = data % 10;

 

 for(p = &addr[index]; *p ; p = &( (*p)->next ) )

 {

  if((*p)->data > data)

   break;

 }

 

 temp = (LinkNode *)malloc(sizeof(LinkNode));

 temp->data = data;

 

 temp->next = *p;

 *p = temp;

 

 return 0;

}

 

 

matrix

 

#ifndef _HEAD_H_ 

#define _HEAD_H_ 

 

typedef int DATATYPE;

 

//链表节点的类型

typedef struct node 

{

 DATATYPE data;

 struct node *next;

}LinkNode;

 

///

typedef struct 

{

 LinkNode *front;

 LinkNode *rear;

}LinkQueue;

 

extern LinkQueue *create_linkqueue();

extern int is_empty_linkqueue(LinkQueue *q);

extern int enter_linkqueue(LinkQueue *q,DATATYPE data);

extern DATATYPE delete_linkqueue(LinkQueue *q);

#endif 

 

 

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include "head.h"

 

#define N 9

 

typedef int VTYPE;

 

typedef struct 

{

 VTYPE v[N];

 int matrix[N][N];

}graph_t;

 

 

graph_t *create_empty_graph()

{

 graph_t *g;

 int i = 0;

 

 g = (graph_t *)malloc(sizeof(graph_t));

 memset(g,0,sizeof(graph_t));

 

 for(i = 0;i < N;i ++)

 {

  g->v[i] = i;

 }

 

 return g;

}

 

int input_graph_edge(graph_t *g)

{

 int i,j;

 

 //输入边的关系

 //(V0,V1) (V0,V2) ... a回车

 

 while(scanf("(V%d,V%d)",&i,&j) == 2)

 {

  getchar();//去掉空格

  g->matrix[i][j] = g->matrix[j][i] = 1;

 }

 

 //清缓存的非法字符

 while(getchar() != '\n');

 

 return 0;

}

 

//输出顶点,和链接矩阵

int printf_graph(graph_t *g)

{

 int i = 0;

 int j = 0;

 

 for(i = 0;i < N;i ++)

 {

  printf("V%d ",g->v[i]);

 }

 printf("\n");

 

 for(i = 0;i < N;i ++)

 {

  for(j = 0;j < N;j ++)

  {

   printf("%d ",g->matrix[i][j]);

  }

  printf("\n");

 }

 

 return 0;

}

 

int visited[N];

 

void BFS(graph_t *g,int v)

{

 //1.创建一个队列

 //2.访问v , visited[v] = 1

 //3.将v进队

 //4.从队列中出队 v = delete_linkqueue(q);

 //  --打印

 //5.找出出队顶点的邻接点

 //for(i = 0;i < N;i ++)

 //{

 // !visited[i] && matrix[v][i] == 1

 // =>条件成立,则i为v的链接点,并且没有被访问 

 // ,访问后进队

 //}

 int i;

 LinkQueue *q = create_linkqueue();

 visited[v] = 1;

 enter_linkqueue(q,v);

 while(!is_empty_linkqueue(q))

 {

  v = delete_linkqueue(q);

  printf("V%d ",v);

  

  for(i = 0;i < N;i ++)

  {

   if(!visited[i] && g->matrix[v][i] == 1)

   {

    visited[i] = 1;

    enter_linkqueue(q,i);

   }

  }

 }

 printf("\n");

 

 return;

}

 

int main()

{

 graph_t *g = create_empty_graph();

 

 input_graph_edge(g);

 

 printf_graph(g);

 BFS(g,0);

 

 return 0;

}

 

#include <stdio.h>

#include <stdlib.h>

#include "head.h"

 

LinkQueue *create_linkqueue()

{

 LinkNode *head;

 LinkQueue *q;

 

 head = (LinkNode *)malloc(sizeof(LinkNode));

 head->next = NULL;

 

 q = (LinkQueue *)malloc(sizeof(LinkQueue));

 q->front = q->rear = head;

 

 return q;

}

 

int is_empty_linkqueue(LinkQueue *q)

{

 return q->front == q->rear ? 1 : 0;

}

 

int enter_linkqueue(LinkQueue *q,DATATYPE data)

{

 LinkNode *temp;

 

 temp = (LinkNode *)malloc(sizeof(LinkNode));

 temp->data = data;

 temp->next = NULL;

 

 //让链表链接

 q->rear->next = temp;

 //更新rear到新的尾部节点

 q->rear       = temp;

 

 return 0;

}

 

DATATYPE delete_linkqueue(LinkQueue *q)

{

 LinkNode *temp;

 

 if(is_empty_linkqueue(q))

 {

  printf("The LinkQueue is empty!\n");

  return (DATATYPE)-1;

 }

 

 temp = q->front;

 q->front = temp->next;

 free(temp);

 return q->front->data;

}

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值