一 图
描述一副图:顶点,边的关系
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;
}