常见数据结构的定义与有关函数
这次数据结构与算法暑期实习用到的数据结构,做一个汇总整理。
图
1.邻接矩阵
邻接矩阵数据结构的定义
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
using namespace std;
#define MaxVertexNum 200 /* 最大顶点数设为200 */
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
/* 边的定义 */
typedef struct ENode* PtrToENode;
struct ENode {
Vertex v1, v2; /* 有向边<V1, V2> */
WeightType weight; /* 权重 */
};
typedef PtrToENode Edge;
/* 图结点的定义 */
typedef struct GNode* PtrToGNode;
struct GNode {
int Nv; /* 顶点数 */
int Ne; /* 边数 */
WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */
函数(初始化图;插入边;建立图)
/* 初始化一个有VertexNum个顶点但没有边的图 */
MGraph CreateGraph(int VertexNum)
{
Vertex v, u;
MGraph Graph;
Graph = (MGraph)malloc(sizeof(struct GNode)); /* 建立图 */
Graph->Nv = VertexNum;
Graph->Ne = 0;
/* 初始化邻接矩阵 */
/* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */
for (v = 0; v < Graph->Nv; v++) {
for (u = 0; u < Graph->Nv; u++) {
Graph->G[v][u] = 0;
}
}
return Graph;
}
/* 插入边 <V1, V2> */
void InsertEdge(MGraph Graph, Edge E)
{
Graph->G[E->v1][E->v2] = E->weight;
/* 若是无向图,还要插入边<V2, V1> */
Graph->G[E->v2][E->v1] = E->weight;
}
MGraph BuildGraph()
{
MGraph Graph;
Edge E;
int Nv, i;
scanf_s("%d", &Nv); /* 读入顶点个数、边的个数 */
Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
scanf_s("%d", &(Graph->Ne)); /* 读入边数 */
if (Graph->Ne != 0) { /* 如果有边 */
E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
/* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */
for (i = 0; i < Graph->Ne; i++) {
scanf_s("%d %d %d", &E->v1, &E->v2, &E->weight);
/* 注意:如果权重不是整型,Weight的读入格式要改 */
InsertEdge(Graph, E);
}
}
return Graph;
}
2.邻接表
邻接表数据结构定义:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
using namespace std;
#define MaxVertexNum 10001 /* 最大顶点数设为10001 */
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
typedef int Elementype;
/* 边的定义 */
typedef struct ENode* PtrToENode;
struct ENode {
Vertex v1, v2;
int weight;
};
typedef PtrToENode Edge;
/* 邻接点的定义 */
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
Vertex AdjV; /* 邻接点下标 */
WeightType weight; /* 边权重 */
PtrToAdjVNode next; /* 指向下一个邻接点的指针 */
};
/*顶点表头结点的定义*/
typedef struct VNode {
PtrToAdjVNode firstEdge;//边表头指针
}AdjList[MaxVertexNum]; //AdjList是邻接表类型
/*图结点的定义*/
typedef struct GNode* PtrToGNode;
typedef PtrToGNode LGraph;
struct GNode {
int Nv;
int Ne;
AdjList G;//邻接表
};
函数(初始化图;插入边;建立图)
/* 初始化一个有VertexNum个顶点但没有边的图 */
LGraph CreateGraph(int VertexNum)
{
Vertex v;
LGraph Graph;
Graph = (LGraph)malloc(sizeof(struct GNode)); /* 建立图 */
Graph->Nv = VertexNum;
Graph->Ne = 0;
/* 初始化邻接表头指针 */
for (v = 1; v <= Graph->Nv; v++) {
Graph->G[v].firstEdge = NULL;
}
return Graph;
}
/* 插入边 <V1, V2>,有向图 */
void InsertEdge(LGraph Graph, Edge E)
{
PtrToAdjVNode newNode;
/*插入边,为V2建立新的邻接点*/
newNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
newNode->AdjV = E->v2;
newNode->weight = E->weight;
/*将v2插入v1的表头*/
newNode->next = Graph->G[E->v1].firstEdge;
Graph->G[E->v1].firstEdge = newNode;
/*无向图*/
newNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
newNode->AdjV = E->v1;
newNode->weight = E->weight;
newNode->next = Graph->G[E->v2].firstEdge;
Graph->G[E->v2].firstEdge = newNode;
}
LGraph BuildGraph()
{
LGraph Graph;
Edge E;
int Nv, i;
PtrToAdjVNode w;
scanf("%d", &Nv); /* 读入顶点个数 */
Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */
scanf("%d", &(Graph->Ne)); /* 读入边数 */
if (Graph->Ne != 0) { /* 如果有边 */
E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */
/* 读入边,格式为"起点 终点",插入邻接矩阵 */
for (i = 1; i <= Graph->Ne; i++) {
scanf("%d %d", &E->v1, &E->v2);
E->weight = 1;
InsertEdge(Graph, E);
}
}
return Graph;
}
线性表
1.栈
堆栈的定义
typedef token ElementType;
//定义堆栈
typedef int position;
typedef struct SNode* PtrToSNode;
struct SNode {
ElementType* data;
position top;
int maxsize;
};
typedef PtrToSNode stack;
栈的常用函数:创建空栈、判断栈满/栈空、入栈、出栈、找栈首元素
//创建空栈
stack CreateStack(int maxsize) {
stack S = (stack)malloc(sizeof(struct SNode));
S->data = (ElementType*)malloc(maxsize * sizeof(ElementType));
S->top = -1;
S->maxsize = maxsize;
return S;
}
//判断栈是否为空
bool IsEmpty(stack S) {
return (S->top == -1);
}
//入栈
void push(stack S, ElementType x) {
S->data[++(S->top)] = x;
}
//出栈
void pop(stack S) {
(S->top)--;
}
//找到栈首元素
ElementType peek(stack S) {
return(S->data[S->top]);
}
2.队列(顺序存储)
结构定义:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define maxsize 10001
/* 队列结构定义(顺序存储)*/
typedef int ElementType;
typedef int position;
typedef struct QNode* PtrToQNode;
struct QNode {
ElementType *data;
position rear;
position front;
int Maxsize;
};
typedef PtrToQNode Queue;
常用函数:创建空队列、判断队空/队满、求队列长度、返回队首元素、入队、出队
/* 创建空队列 */
Queue CreateQueue(int Maxsize)
{
Queue Q;
/*申请获得队列空间*/
Q = (Queue)malloc(sizeof(struct QNode));
Q->data = (ElementType*)malloc(Maxsize* sizeof(ElementType));
Q->front = Q->rear = 0;
Q->Maxsize = Maxsize;
return Q;
}
/* 判断队列是否为空 */
bool IsEmptyQ(Queue Q)
{
return Q->front == Q->rear;
}
/* 判断队列是否为满 */
bool IsFullQ(Queue Q)
{
return (Q->rear + 1) % Q->Maxsize == Q->front;
}
/* 队列长度 */
int QueueSize(Queue Q)
{
return (Q->rear - Q->front + Q->Maxsize) % Q->Maxsize;
}
/* 入队 */
bool pushQ(Queue Q, ElementType X)
{
if (IsFullQ(Q)) {
printf("队列满");
return false;
}
else {
Q->rear = (Q->rear + 1) % Q->Maxsize;
Q->data[Q->rear] = X;
return true;
}
}
/* 出队 */
bool popQ(Queue Q)
{
if (IsEmptyQ(Q)) {
printf("队列空");
return false;
}
else {
Q->front = (Q->front + 1) % Q->Maxsize;
return true;
}
}
/*返回队首元素*/
int FrontQ(Queue Q) {
return Q->data[Q->front];
}
2.队列(链式存储)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define maxsize 10001
/* 队列结构定义(链式存储)*/
typedef int ElementType;
typedef int position;
typedef struct Node* PtrToNode;
struct Node {
ElementType data;
PtrToNode next;
};
typedef PtrToNode position;
typedef struct QNode* PtrToQNode;
struct QNode {
position rear;
position front;
int Maxsize;
};
typedef PtrToQNode Queue;
/* 判断队列是否为空 */
bool IsEmptyQ(Queue Q)
{
return Q->front == NULL;
}
/* 出队 */
bool popQ(Queue Q)
{
position frontcell;
ElementType frontelem;
if (IsEmptyQ(Q)) {
printf("队列空");
return false;
}
else {
frontcell = Q->front;
if (Q->front ==Q->rear ) {
Q->front = Q->rear = NULL;
}
else {
Q->front = Q->front->next;
}
frontelem = frontcell->data;
free(frontcell);
return frontelem;
}
}
3.优先队列
二叉树
结构定义
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define _CRT_SECURE_NO_WARNINGS
#define maxsize 1000
#define NULL -1
typedef int ElementType;
typedef int BinTree;
/*二叉树结构定义*/
struct TNode
{
ElementType data; //结点数据
BinTree leftchild;//指向左子树
BinTree rightchild;//指向右子树
} T1[maxsize],T2[maxsize];
函数
/*创建二叉树,返回根结点*/
BinTree CreateBinTree( struct TNode T[] )
{
int i, n;
char data,l,r;
BinTree root = NULL;
int flag[maxsize];//建立一个标签数组,辅助判断树的根结点。
memset(flag, 0, sizeof(flag));//先都初始化为0
scanf("%d", &n);
if (n) {
for ( i=0; i<n; i++ ) {
scanf("\n%c %c %c",&data, &l, &r);//这一步在VS2019中会报错“访问冲突”,在codeblocks中运行正常。
T[i].data=data;
if ( l != '-' ) {
T[i].leftchild = l-'0';
flag[T[i].leftchild] = 1;
} else {
T[i].leftchild = NULL;
}
if ( r != '-' ) {
T[i].rightchild = r-'0';//-'0'是为了让char转化为int类型。
flag[T[i].rightchild] = 1;
} else {
T[i].rightchild = NULL;
}
}
for ( i=0; i<n; i++ ) {
if ( flag[i]==0 ) {
/*若标记为0,则是根结点*/
root = i;
}
}
}
return root;
}