线性表
顺序表
- 结构体
#define SequenceMaxsize 100
typedef int ElementType;
//TODO: 数组静态分配
typedef struct {
ElementType data[SequenceMaxsize];
int size;
} SqList_Static;
//TODO: 数组动态分配
//typedef struct {
// ElementType *data;
// int length;
//} SqList_Dynamic;
- 具体函数实现
/**
* 前插
* @param sqList
* @param i
* @param e
*/
bool ListInsert(SqList_Static *sqList, int i, ElementType e) {
if (i < 0 || i >= sqList->size + 1) return false;
if (sqList->size == SequenceMaxsize) return false;
for (int j = sqList->size; j >= i; j--) {
sqList->data[j] = sqList->data[j - 1];
}
sqList->data[i] = e;
sqList->size++;
return true;
}
/**
* 构造函数,使得线性表大小等于0
* @param sqList 线性表对象
*/
void InitList(SqList_Static *sqList) {
sqList->size = 0;
FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
if (file==NULL){
printf("file open error!");
return;
} else{
char ch[1024];
int i = 0;
while (!feof(file)) {
fgets(ch, 1024, file);
//ch[strlen(ch) - 1] = '\0';
//printf("%s\n", ch);
ListInsert(sqList, i, atoi(ch));
i++;
}
fclose(file);
}
}
/**
* 输出
* @param sqList
*/
void PrintList(SqList_Static sqList) {
for (int i = 0; i < sqList.size; i++) {
printf("%d ", sqList.data[i]);
}
}
/**
* 取值
* @param sqList
* @param i
* @return
*/
ElementType GetElem(SqList_Static sqList, int i) {
return sqList.data[i];
}
/**
* 判空
* @param sqList
* @return
*/
bool Empty(SqList_Static sqList) {
return (sqList.size == 0) ? true : false;
}
/**
* 长度
* @param sqList
* @return
*/
int Length(SqList_Static sqList) {
return sqList.size;
}
/**
* 返回元素e所在位置,返回值从1开始,到 <sqList.size> ,sqList中不存在元素e,则返回0
* @param sqList list
* @param e 元素e
* @return 所在位置
*/
int LocateElem(SqList_Static sqList, ElementType e) {
for (int i = 0; i < sqList.size; i++) {
if (sqList.data[i] == e) return i + 1;
}
return 0;
}
/**
* 删除
* @param sqList
* @param i
* @param e 返回被删除元素的引用
*/
bool ListDelete(SqList_Static *sqList, int i, ElementType *e) {
if (i < 1 || i > sqList->size) return false;
*e = sqList->data[i - 1];
for (int j = i; j < sqList->size; j++) {
sqList->data[j - 1] = sqList->data[j];
}
sqList->size--;
return true;
}
/**
* 销毁线性表
* @param sqList 线性表对象
*/
void DestroyList(SqList_Static *sqList) {
free(sqList);
}
/**
* 顺序表的逆置
* @param sqList
*/
void Reverse(SqList_Static *sqList) {
int i = 0;
int j = sqList->size - 1;
while (i < j) {
int temp = sqList->data[i];
sqList->data[i] = sqList->data[j];
sqList->data[j] = temp;
i++;
j--;
}
}
- 笔记
<stdlib.h>头文件中有两个函数,int atoi(char *p)和char *itoa(int p),分别将装有整数的char数组转化为整数,和将整数按位数分解依次存入char数组中。
C语言中,free可以释放calloc, malloc, realloc动态分配的空间。
首先说明一下,释放的不是你定义的指针,而是你定义的指针指向的空间。
至于你定义的普通指针是不是可以通过free释放,这个要看情况。如果你定义的指针指向动态分配的地址空间,则可以使用free释放指针指向的这段空间;否则,就不能使用free释放指针指向的空间。下面举两个例子:
例1:char p = NULL; p = (char)malloc(1024); if (p != NULL) free§;
例2:char p = NULL; char buf[1024]; p = (char)buf; free§;
其中,例1是对的,例2是错误的。
值传递与址传递:ListDelete: *e = sqList->data[i - 1];
三元表达式: return (sqList.size == 0) ? true : false;
单链表
- 结构体
typedef int ElemType;
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
- 具体函数实现
/**
* 带头结点-头插法建立单链表
* @param linkList
* @return
*/
LinkList ListHeadInsert(LinkList linkList) {
FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
linkList = (LinkList) malloc(sizeof(LinkList));
linkList->next = NULL;
LinkList temp;
if (file == NULL) {
printf("file open error!");
} else {
while (!feof(file)) {
char ch[1024];
fgets(ch, 1024, file);
temp = (LinkList) malloc(sizeof(LinkList));
temp->data = atoi(ch);
printf("%d-", temp->data);
temp->next = linkList->next;
linkList->next = temp;
}
}
return linkList;
}
/**
* 带头结点-尾插法建立单链表
* @param linkList
* @return
*/
LinkList ListTailInsert(LinkList linkList) {
FILE *file = fopen("E:\\DataStructure\\PostGraduate\\LinearList\\text", "r");
linkList = (LinkList) malloc(sizeof(LinkList));
linkList->next = NULL;
LinkList temp, r = linkList;
if (file == NULL) {
printf("file open error!");
} else {
char ch[1024];
while (!feof(file)) {
fgets(ch, 1024, file);
temp = (LinkList) malloc(sizeof(LinkList));
temp->data = atoi(ch);
r->next = temp;
r = temp;
}
r->next = NULL;
}
return linkList;
}
/**
* 输出链表
* @param linkList
*/
void PrintLinkList(LinkList linkList) {
if (linkList == NULL) {
printf("linklist is null!");
return;
}
LinkList p = linkList;
while (p->next != NULL) {
p = p->next;
printf("%d ", p->data);
}
}
/**
* 按序号查找
* 返回带有头节点的链表序列
* @param linkList
* @return
*/
LinkList GetElemFromI(LinkList linkList, int i) {
LinkList p = linkList;
if (i == 0) return linkList;
if (i < 1) return NULL;
while (p && i > 0) {
p = p->next;
i--;
}
LinkList res;
res = (LinkList) malloc(sizeof(LinkList));
res->next = p;
return res;
}
/**
* 按值查找
* 返回带有头节点的链表序列
* @param linkList
* @return
*/
LinkList GetElemFromV(LinkList linkList, ElemType e) {
LinkList p = linkList;
while (p != NULL && p->data != e) {
p=p->next;
}
LinkList res;
res = (LinkList) malloc(sizeof(LinkList));
res->next = p;
return res;
}
/**
* 插入操作(前插)
* @param linkList
* @param i 插入位置 - 从1开始
* @param e 插入元素
* @return
*/
LinkList InsertI(LinkList linkList, int i, ElemType e) {
if (i <= 0) return NULL;
LinkList p = linkList;
while (i > 1) {
p = p->next;
i--;
}
LinkList t;
t = (LinkList) malloc(sizeof(LinkList));
t->data = e;
t->next = p->next;
p->next = t;
return linkList;
}
/**
* 按位删除
* @param linkList
* @param i 删除第i个元素
* @return
*/
LinkList DeleteElemFromI(LinkList linkList, int i) {
if (i <= 0) return NULL;
LinkList p = linkList;
while (p && i > 1) {
p = p->next;
i--;
}
if (p){
LinkList q = p->next;
p->next = q->next;
free(q);
}
return linkList;
}
/**
* 求表长
* @param linkList
* @return
*/
int LinkListLength(LinkList linkList) {
int i = 0;
LinkList p = linkList;
p = p->next;
while (p) {
p = p->next;
i++;
}
return i;
}
/**
* 链表逆置
* @param linkList
* @return
*/
LinkList LinkListReverse(LinkList linkList) {
LinkList p = linkList;
LinkList r, temp;
r = GetElemFromI(linkList, LinkListLength(linkList));
r = r->next;
while (p->next != r) {
temp = p->next;
p->next = temp->next;
temp->next = r->next;
r->next = temp;
}
return linkList;
}
对链表中间的一个链表对象使用free函数后,该对象后面的所有元素没有被free掉。同时记住让该对象的前一个对象的next指针置空。
- 逆置
双链表
- 结构体
typedef int ElemType;
typedef struct DNode {
ElemType data;
struct DNode *prior, *next;
} DNode, *DLinkList;
栈
- 结构体
#define MAXSIZE 100
typedef int ElemType;
typedef struct {
ElemType data[MAXSIZE];
int top;
} SqStack;
- 函数实现
/**
* 初始化
* @param sqStack
*/
void InitStack(SqStack *sqStack) {
sqStack->top = -1;
}
/**
* 判空
* @param sqStack
* @return
*/
bool StackEmpty(SqStack sqStack) {
if (sqStack.top == -1) return true;
else return false;
}
/**
* 栈满:sqStack->top == MAXSIZE-1
* @param sqStack
* @param e 保存并返回,以便 free
* @return
*/
bool Push(SqStack *sqStack, ElemType e) {
if (sqStack->top == MAXSIZE - 1) return false;
sqStack->data[++sqStack->top] = e;
return true;
}
/**
*
* @param sqStack
* @param e 保存并返回,以便 free
* @return
*/
bool Pop(SqStack *sqStack, ElemType *e) {
if (sqStack->top == -1) return false;
*e = sqStack->data[sqStack->top];
sqStack->top--;
}
/**
* 读取栈顶元素
* @param sqStack
* @param e 的返回值
* @return
*/
bool GetTop(SqStack sqStack, ElemType *e) {
if (StackEmpty(sqStack)) return false;
*e = sqStack.data[sqStack.top];
return true;
}
void ClearStack(SqStack *sqStack) {
sqStack->top = -1;
}
队列
- 结构体
#define Maxsize 100
typedef int ElemType;
typedef struct {
ElemType data[Maxsize];
int front, rear;
} Queue;
- 函数实现
void InitQueue(Queue *queue) {
queue->front = queue->rear = 0;
}
bool QueueEmpty(Queue queue) {
if (queue.rear == queue.front) return true;
else return false;
}
bool EnQueue(Queue *queue, ElemType e) {
if ((queue->rear + 1) % Maxsize == queue->front) return false;
queue->data[queue->rear] = e;
queue->rear = (queue->rear + 1) % Maxsize;
return true;
}
bool DeQueue(Queue *queue, ElemType *e) {
if (queue->front == queue->rear) return false;
*e = queue->data[queue->front];
queue->front = (queue->front + 1) % Maxsize;
return true;
}
void GetHead(Queue queue, ElemType *e) {
*e = queue.data[queue.front];
}
int GetSize(Queue queue) {
return queue.rear - queue.front;
}
void ClearQueue(Queue *queue) {
queue->front = queue->rear = 0;
}
栈的应用
- 括号匹配
/**
* 匹配
* @param a 左括号
* @param b 右括号
* @return
*/
bool match(char a, char b) {
if (a + 1 == b || a + 2 == b) return true;
else return false;
}
/**
* 括号匹配
* @return
*/
bool BracketMatch(SqStack stack, const char str[]) {
ElemType e;
for (int i = 0; i < strlen(str); ++i) {
switch (str[i]) {
case '{':
case '[':
case '(':
Push(&stack, str[i]);
break;
case '}':
case ']':
case ')':
GetTop(stack, &e);
if (match(e, str[i])) Pop(&stack, &e);
else return false;
break;
default:
break;
}
}
if (StackEmpty(stack)) return true;
else return false;
}
int main() {
SqStack stack;
InitStack(&stack);
char str[] = "{[())]}";
printf("match = %d\n", BracketMatch(stack, str) ? 1 : 0);
}
左括号与右括号,ASCII:“(”与“)”相差1,“[”与“]”,“{”与“}”相差2
- 后缀表达式求值
/**
* 读取char数组中的值
* @param str
* @param i 从第i个位置开始
* @return double类型
*/
double ReadNumber(char str[], int *i) {
double res = 0.0;
int k = 0;//标记小数位数
//处理整数部分
while (str[*i] <= '9' && str[*i] >= '0') {
res = res * 10 + (str[*i] - '0');
(*i)++;
}
//处理小数部分
if (str[*i] == '.') {
(*i)++;
while (str[*i] <= '9' && str[*i] >= '0') {
res = res * 10 + (str[*i] - '0');
(*i)++;
k++;
}
}
while (k != 0) {
res = res / 10.0;
k--;
}
return res;
}
/**
* 后缀表达式求值
* @param str
* @return 算下的结果
*/
double SuffixValue(char str[]) {
SqStack stack;
InitStack(&stack);
int i = 0;
ElemType x1, x2;
while (str[i] != '#') {
if (str[i] <= '9' && str[i] >= '0') {
Push(&stack, ReadNumber(str, &i));
} else if (str[i] == ' ') {
i++;
} else if (str[i] == '+') {
Pop(&stack, &x2);
Pop(&stack, &x1);
Push(&stack, x1 + x2);
i++;
} else if (str[i] == '-') {
Pop(&stack, &x2);
Pop(&stack, &x1);
Push(&stack, x1 - x2);
i++;
} else if (str[i] == '*') {
Pop(&stack, &x2);
Pop(&stack, &x1);
Push(&stack, x1 * x2);
i++;
} else if (str[i] == '/') {
Pop(&stack, &x2);
Pop(&stack, &x1);
Push(&stack, x1 / x2);
i++;
}
}
GetTop(stack, &x1);
return x1;
}
int main() {
// char str[] = "3 5 2 * - #";
char str[] = "3 5 - 2 * #";
printf("%f\n", SuffixValue(str));
}
- 中缀表达式转变为后缀表达式
/**
* 判断是否为操作符号
* @param op
* @return
*/
bool is_operation(char op) {
switch (op) {
case '+':
case '-':
case '*':
case '/':
return true;
default:
return false;
}
}
/**
* 返回操作符的优先级
* @param op
* @return
*/
int Priority(char op) {
switch (op) {
case '#':
return -1;
case '(':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return -1;
}
}
/**
* 转变体,输出即为后缀表达式
* @param infix 中缀
* @param suffix 后缀
*/
void Suffix(char infix[], char suffix[]) {
SqStack stack;
InitStack(&stack);
ElemType e;
int i = 0;
while (infix[i] != '#') {
if ((infix[i] <= '9' && infix[i] >= '0') || infix[i] == '.') {
printf("%d ", infix[i] - '0');
} else if (infix[i] == '(') {
Push(&stack, infix[i]);
} else if (infix[i] == ')') {
GetTop(stack, &e);
while (e != '(') {
printf("%c ", e);
Pop(&stack, &e);
GetTop(stack, &e);
}
Pop(&stack, &e);
} else if (is_operation(infix[i])) {
GetTop(stack, &e);
if (StackEmpty(stack)) {
Push(&stack, infix[i]);
} else if (e == '(') {
Push(&stack, infix[i]);
} else if (Priority(e) < Priority(infix[i])) {
Push(&stack, infix[i]);
} else {
GetTop(stack, &e);
while (Priority(e) >= Priority(infix[i]) || e == '(') {
printf("%c ", e);
Pop(&stack, &e);
GetTop(stack, &e);
}
Push(&stack, infix[i]);
}
}
i++;
}
while (!StackEmpty(stack)) {
GetTop(stack, &e);
printf("%c ", e);
Pop(&stack, &e);
}
}
int main() {
char infix[] = "4 * ( 2 + 1 ) #";
char suffix[] = "4 * ( 2 + 1 ) #";
Suffix(infix, suffix);
}
树
- 双亲表示法
#define MAXSIZE 100
typedef char datatype;
typedef struct node {
datatype data;
int parent;
} temp;
typedef struct parent_tree {
temp treeList[MAXSIZE];
int length, root; //root:根节点的下标
};
- 孩子表示法(数组)
#define DEGREE 3
#define MAXSIZE 20
typedef char datatype;
typedef struct child_array {
datatype data;
int child[DEGREE];
} child_array_tree;
child_array_tree tree[MAXSIZE];
int root;
int length;
- 孩子表示法(链表)
#define MAXSIZE 50
typedef char datatype;
typedef struct child_node {
int child;
struct child_node *next;
} child_node, *child_point;
typedef struct {
datatype data;
child_point first_child;
} temp;
typedef struct {
temp treeList[MAXSIZE];
int length,root;
}child_tree;
二叉树
- 结构体
typedef char datatype;
typedef struct bint_node {
datatype data;
struct bint_node *left, *right;
} bint_node, *bin_tree;
bin_tree root;
- 函数实现
/**
* 以先序遍历序列创建二叉树
* 输入示例:abd#e##fg###c##
* @return
*/
bin_tree createBinTree() {
bin_tree tree;
char ch;
if ((ch = getchar()) == '#') {
tree = NULL;
} else {
tree = (bin_tree) malloc(sizeof(bin_tree));
tree->data = ch;
printf("%c-", ch);
tree->left = createBinTree();
tree->right = createBinTree();
}
return tree;
}
/**
* 先序遍历
* 递归
* @param tree
*/
void preOrder(bin_tree tree) {
if (tree) {
printf("%c ", tree->data);
preOrder(tree->left);
preOrder(tree->right);
}
}
/**
* 中序遍历
* 递归
* @param tree
*/
void inOrder(bin_tree tree) {
if (tree) {
inOrder(tree->left);
printf("%c ", tree->data);
inOrder(tree->right);
}
}
/**
* 后序遍历
* 递归
* @param tree
*/
void postOrder(bin_tree tree) {
if (tree) {
postOrder(tree->left);
postOrder(tree->right);
printf("%c ", tree->data);
}
}
- 非递归遍历(栈)
/**
* 先序遍历
* 非递归
* @param tree
*/
void preOrder1(bin_tree tree) {
binStack stack;
stack.top = -1;
while (tree || stack.top != -1) {
if (tree) {
printf("%c-", tree->data);
Push(&stack, tree);
tree = tree->left;
} else {
tree = Pop(&stack);
tree = tree->right;
}
}
}
/**
* 中序遍历
* 非递归
* @param tree
*/
void inOrder1(bin_tree tree) {
binStack stack;
stack.top = -1;
while (tree || stack.top != -1) {
if (tree) {
binPush(&stack, tree);
tree = tree->left;
} else {
tree = binPop(&stack);
printf("%c-", tree->data);
tree = tree->right;
}
}
}
/**
* 后序遍历
* 非递归
* @param tree
*/
void postOrder1(bin_tree tree) {
binStack stack;
stack.top = 0;
while (tree || stack.top != -1) {
if (tree) {
stack.data[stack.top] = tree;
stack.tag[stack.top] = 0;
stack.top++;
tree = tree->left;
} else {
if (stack.tag[stack.top - 1] == 1) {
stack.top--;
tree = stack.data[stack.top];
printf("%c-", tree->data);
tree = NULL;
} else {
tree = stack.data[stack.top - 1];
stack.tag[stack.top - 1] = 1;
tree = tree->right;
}
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KNM94d4x-1572164742740)(https://github.com/xieyipeng/MarkdownPic/blob/master/841446E1D1B4BFAEF26CA0290755E62D.JPG)])
- 层次遍历(队列)
/**
* 层次遍历
* @param tree
*/
void levelOrder(bin_tree tree) {
binQueue queue;
init_binQueue(&queue);
EnBinQueue(&queue, tree);
bin_tree temp;
while (queue.front != queue.rear) {
DeBinQueue(&queue, &temp);
printf("%c-",temp->data);
if (temp->left!=NULL){
EnBinQueue(&queue,temp->left);
}
if (temp->right!=NULL){
EnBinQueue(&queue,temp->right);
}
}
}
- 节点个数(递归)
/**
* 返回二叉树的节点数目
* @param tree
*/
int numOfNode(bin_tree tree) {
if (tree == NULL) return 0;
else return numOfNode(tree->left) + numOfNode(tree->right) + 1;
}
- 等价(递归)
/**
* 判断两颗二叉树是否等价
* @param tree1
* @param tree2
* @return
*/
int isEqual(bin_tree tree1, bin_tree tree2) {
int t = 0;
if (tree1 == NULL && tree2 == NULL) t = 1;
else if (tree1 != NULL && tree2 != NULL)
if (tree1->data == tree2->data)
if (isEqual(tree1->left, tree2->left))
t = isEqual(tree1->right, tree2->right);
return (t);
}
- 二叉树高度(递归)
/**
* 返回树的深度
* @param tree
* @return
*/
int depth(bin_tree tree) {
int h, lh, rh;
if (tree == NULL) h = 0;
else {
lh = depth(tree->left);
rh = depth(tree->right);
if (lh >= rh) h = lh + 1;
else h = rh + 1;
}
return h;
}
图
因本人节点从1开始计数,造成很多麻烦,代码中可能i,j之类的不能直接使用,需要稍微修改
- 邻接矩阵法(结构体)
#define MAXSIZE 100
typedef char VertexType;
typedef int EdgeType;
typedef struct {
VertexType vertex[MAXSIZE];
EdgeType edge[MAXSIZE][MAXSIZE];
int n, e;
} MGraph;
- 建立图
/**
* 邻接矩阵创建图
* @param graph 边的数组从1开始
* @param c 有向(1)或无向(0)图
*/
void create(MGraph *graph, int c) {
graph->n = 0;
graph->e = 0;
int i, j;
char ch[20];
FILE *edge = fopen("E:\\DataStructure\\PostGraduate\\graph\\edge.txt", "r");
FILE *vertex = fopen("E:\\DataStructure\\PostGraduate\\graph\\vertex.txt", "r");
if (!edge || !vertex) {
printf("file open error!!");
} else {
while (!feof(vertex)) {
fscanf(vertex, "%d", &graph->vertex[graph->n]);
graph->n++;
}
for (int m = 0; m <= graph->n; ++m) {
for (int k = 0; k <= graph->n; ++k) {
graph->edge[m][k] = FINITY;
}
}
while (!feof(edge)) {
fscanf(edge, "%d %d %s", &i, &j, ch);
graph->edge[i][j] = atof(ch);
if (c == 0) {
graph->edge[j][i] = atof(ch);
}
graph->e++;
}
}
}
fscanf读到空格或者回车时会把空格或回车转化为/0(字符串结束符)而fgets函数则把空格(回车在下文解释)作为字符接收。
- 深度优先遍历
bool visited[MAXSIZE];
void dfs(MGraph graph, int i) {
printf("%d->", graph.vertex[i - 1]); //输出序列
visited[i] = true;
for (int j = 1; j <= graph.n; ++j) {
if (!visited[j] && graph.edge[i][j] != FINITY) {
dfs(graph, j);
}
}
}
/**
* 标记位从0开始,实际节点编号从1开始
* @param graph
*/
void dfsTraverse(MGraph graph) {
for (int i = 1; i <= graph.n; ++i) {
visited[i] = false;
}
for (int i = 1; i <= graph.n; ++i) { //用于有多个图
if (!visited[i]) dfs(graph, i);
}
}
- 广度优先遍历
void bfs(MGraph graph, int i) {
if (!visited[i]) {
printf("%d->", graph.vertex[i - 1]);
visited[i] = true;
}
int temp[MAXSIZE];
int rear = 0, front = 0;
for (int j = 1; j <= graph.n; ++j) {
if (!visited[j] && graph.edge[i][j] != FINITY) {
//访问并入队
printf("%d->", graph.vertex[j - 1]);
visited[j] = true;
temp[rear] = j;
rear++;
}
}
while (rear != front) {
bfs(graph, temp[front]);
front++;
}
}
/**
* bfs广度优先遍历
* @param graph
* @return 连通分量的个数
*/
int bfsTraverse(MGraph graph) {
int count = 0;
for (int i = 1; i <= graph.n; ++i) {
visited[i] = false;
}
for (int j = 1; j <= graph.n; ++j) {
dfs(graph, j);
count++;
}
return count;
}
- 最小生成树(prim)
/**
* 最小生成树prim算法
* @param graph
*/
void prim(MGraph graph) {
edge tree[graph.n - 1];
edge temp;
EdgeType min, d;
int s = 0, v;
for (int i = 1; i <= graph.n; ++i) {
tree[i - 1].begin = 1;
tree[i - 1].end = i + 1;
tree[i - 1].length = graph.edge[1][i + 1];
}
for (int k = 0; k <= graph.n - 3; ++k) {
min = tree[k].length;
s = k;
for (int j = k + 1; j <= graph.n - 2; ++j) {
if (tree[j].length < min && tree[j].length != FINITY) {
min = tree[j].length;
s = j;
}
}
v = tree[s].end;
temp = tree[s];
tree[s] = tree[k];
tree[k] = temp;
for (int j = k + 1; j <= graph.n - 2; ++j) {
d = graph.edge[v][tree[j].end];
if (d < tree[j].length) {
tree[j].length = d;
tree[j].begin = v;
}
}
}
printf("the minimum cost spanning tree is :\n");
for (int j = 0; j <= graph.n - 2; ++j) {
printf("%d---%d %.2f \n", tree[j].begin, tree[j].end, tree[j].length);
}
printf("the root is %d\n", graph.vertex[0]);
}
- 最小生成树(kruskal)
/**
* 对边排序
* @param edges
* @param left
* @param right
*/
void sort(edge *edges, int left, int right) {
int i = 0, j = 0;
edge x;
if (left < right) {
i = left;
j = right;
x = edges[i];
while (i < j) {
while (i < j && x.length < edges[j].length) j--;
if (i < j) edges[i++] = edges[j];
while (i < j && x.length > edges[i].length) i++;
if (i < j) edges[j--] = edges[i];
}
edges[i] = x;
sort(edges, left, i - 1);
sort(edges, i + 1, right);
}
}
void GetEdge(MGraph graph, edge edges[]) {
int count = 0;
for (int i = 0; i <= graph.n; ++i) {
for (int j = 0; j < i; ++j) {
if (graph.edge[i][j] != 0 && graph.edge[i][j] != FINITY) {
edges[count].begin = i;
edges[count].end = j;
edges[count].length = graph.edge[i][j];
count++;
}
}
}
}
/**
* kruskal算法
* @param graph
*/
void kruskal(MGraph graph) {
int k = 0;
int cnvx[graph.n];
edge edges[graph.e];
edge tree[graph.n - 1];
GetEdge(graph, edges);
sort(edges, 0, graph.e - 1);
for (int j = 0; j < graph.n; ++j) {//初始化连通分量
cnvx[j] = j;
}
for (int i = 0; i < graph.n - 1; ++i) {
while (cnvx[edges[k].begin - 1] == cnvx[edges[k].end - 1]) k++;
tree[i] = edges[k];
int temp = cnvx[edges[k].end - 1];
for (int j = 0; j < graph.n; ++j) {
if (cnvx[j] == temp) {
cnvx[j] = cnvx[edges[k].begin - 1];
}
}
k++;
}
printf("the minimum cost spanning tree is :\n");
for (int l = 0; l < graph.n - 1; ++l) {
printf("%d---%d %.2f \n", tree[l].begin, tree[l].end, tree[l].length);
}
}
- 单源最短路径算法(dijkstra)
void print_pgd(MGraph graph, int path[], float dist[]) {
for (int j = 0; j < graph.n; ++j) {
path[j] = path[j] - 1;
}
int st[graph.n], pre, top = -1;
for (int i = 0; i < graph.n; ++i) {
printf("\nDistance: %.2f , path: ", dist[i]);
st[++top] = i;
pre = path[i];
while (pre != -1) {
st[++top] = pre;
pre = path[pre];
}
while (top > 0) {
printf("%2d", (st[top--] + 1));
}
}
}
/**
* dijkstra算法求单源最短路径
* @param graph
* @param v0
*/
void dijkstra(MGraph graph, int v0) {
float min = 0;
int v = 0;
float dist[graph.n];
int path[graph.n];
bool final[graph.n];
for (int i = 0; i < graph.n; ++i) {
final[i] = false;
dist[i] = graph.edge[v0][i + 1];
if (dist[i] < FINITY && dist[i] != 0) path[i] = v0;
else path[i] = 0;
}
final[v0 - 1] = true;
dist[v0 - 1] = 0;
for (int i = 2; i <= graph.n; ++i) {
//找到dist内最小距离
min = FINITY;
for (int k = 0; k < graph.n; ++k) {
if (!final[k] && dist[k] < min) {
v = k;
min = dist[k];
}
}
printf("%d---%.2f\n", v, min);
if (min == FINITY) {
return;
} else {
final[v] = true;
}
final[v] = true;
//修改dist和path数组
for (int k = 0; k < graph.n; ++k) {
if (!final[k] && (min + graph.edge[v + 1][k + 1] < dist[k])) {
dist[k] = min + graph.edge[v + 1][k + 1];
path[k] = v + 1;
}
}
}
print_pgd(graph, path, dist);
}
- Floyd算法求最短路径
/**
* floyd算法
* @param graph
*/
void floyd(MGraph graph) {
int dist[graph.n][graph.n];
int path[graph.n][graph.n];
for (int i = 0; i < graph.n; ++i) {
for (int j = 0; j < graph.n; ++j) {
dist[i][j] = graph.edge[i][j];
if (i != j && dist[i][j] < FINITY) {
path[i][j] = i;
} else {
path[i][j] = -1;
}
}
}
for (int k = 0; k < graph.n; ++k) {
for (int i = 0; i < graph.n; ++i) {
for (int j = 0; j < graph.n; ++j) {
if (dist[i][j] > (dist[i][k] + dist[k][j])) {
dist[i][j] = dist[i][k] + dist[k][j];
path[i][k] = k;
}
}
}
}
}
查找
- kmp算法
/**
* next数组
* @param p
* @param next
*/
void getNext(seqString p, int next[]) {
next[0] = -1;
int i = 0;
int j = -1;
while (i < p.length) {
if (j == -1 || p.str[i] == p.str[j]) {
++i;
++j;
next[i] = j;
} else {
j = next[j];
}
}
}
/**
* 模式匹配kmp算法
*/
int kmp(seqString t, seqString p, int next[]) {
int i = 0;
int j = 0;
while (i < t.length && j < p.length) {
if (j==-1||t.str[i]==p.str[j]){
i++;
j++;
} else{
j=next[j];
}
}
if (j==p.length) return (i-p.length);
else return (-1);
}
排序
- 插入排序
strlen只可以用来测量char*字符串的长度,求数组长度(比如int a[])要用sizeof(a)/sizeof(int)
/**
* 直接插入排序
* @param a
* @param n
*/
void insertSort(ElemType a[], int n) {
int sentry = 0;
for (int i = 1; i < n; ++i) {
int j = i - 1;
sentry = a[i];
while (sentry < a[j]) {
a[j + 1] = a[j];
j--;
}
a[j + 1] = sentry;
}
}
/**
* 折半查找
* @param a
* @param n
*/
void binary(ElemType a[], int n) {
int sentry = 0;
int low = 0, high = 0;
for (int i = 1; i < n; ++i) {
sentry = a[i];
low = 0;
high = i;
//查找
while (low <= high) {
int mid = (low + high) / 2;
if (sentry < a[mid]) high = mid - 1;
else low = mid + 1;
}
//移动
for (int j = i - 1; j >= high + 1; --j) {
a[j + 1] = a[j];
}
a[low] = sentry;
}
}
/**
* 希尔排序
* @param a
* @param n
*/
void shellSort(ElemType a[], int n) {
int d = n / 2;
int sentry;
while (d >= 1) {
for (int i = d; i < n; ++i) {
sentry = a[i];
int j = i - d;
while (j >= 0 && sentry < a[j]) {
a[j + d] = a[j];
j = j - d;
}
a[j + d] = sentry;
}
print_sort(a,n);
d = d / 2;
}
}
-
希尔排序
-
交换排序
/**
* 冒泡排序
* @param a
* @param n
*/
void bubbling(ElemType a[], int n) {
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
/**
* 快速排序
* @param a
* @param low
* @param high
*/
void quick(ElemType a[], int low, int high) {
if (low < high) {
int i = low;
int j = high;
int sentry = a[low];
while (i != j) {
while (sentry < a[j] && i < j) j--;
if (i < j) {
a[i] = a[j];
i++;
}
while (sentry > a[i] && i < j) i++;
if (i < j) {
a[j] = a[i];
j--;
}
}
a[i] = sentry;
quick(a, low, i - 1);
quick(a, i + 1, high);
}
}
- 选择排序
/**
* 选择排序
* @param a
* @param i
*/
void select(ElemType a[], int n) {
for (int j = 0; j < n - 1; ++j) {
int min = j;
for (int i = j+1; i < n; ++i) {
if (a[i]<a[min]) min=i;
}
if (min!=j){
ElemType temp=a[j];
a[j]=a[min];
a[min]=temp;
}
}
}