咱本地编译过了、保证OK
github地址:github.com/nppp1990/st…
排序算法
冒泡排序
#include <stdio.h>
void bubbleSort(int arr[], int len) {
int i, j, temp;
int flag;
for (i = 0; i < len - 1; i++) {
flag = 0;
for (j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = 1;
}
}
if (flag == 0) {
// 说明没有需要交换的数,说明所有的数已排序
return;
}
}
}
void testBubbleSort() {
printf("\n-----bubbleSort-----begin\n");
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 };
int len = (int) sizeof(arr) / sizeof(*arr);
bubbleSort(arr, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----bubbleSort-----end\n");
}
选择排序
#include <stdio.h>
void selectSort(int arr[], int len) {
int i, j, temp;
for (i = 0; i < len - 1; i++) {
int min = i;
for (j = i + 1; j < len; j++) {
if (arr[j] < arr[min]) {
//记录最小值的位置
min = j;
}
}
//最小值和i交换
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
void testSelectSort() {
printf("\n-----selectSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
selectSort(arr, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----selectSort-----end\n");
}
插入排序
#include <stdio.h>
void insertSort(int arr[], int len) {
int i, j, key;
for (i = 1; i < len; i++) {
key = arr[i];
j = i - 1;
while ((j >= 0) && (arr[j] > key)) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
void testInsertSort() {
printf("\n-----insertSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
insertSort(arr, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----insertSort-----begin\n");
}
快速排序
#include <stdio.h>
int quickSort(int arr[], int left, int right) {
if (left >= right) {
// 递归结束的条件
return 0;
}
// 指针p指向left
int p = arr[left];
int i = left;
int j = right;
while (i < j) {
while (i < j && arr[j] >= p) {
// 从最右往左找到第一个小于p的位置j
j--;
}
while (i < j && arr[i] <= p) {
// 从左往右找到第一个大于p的位置i
i++;
}
if (i < j) {
// 交换i和j
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// i和j相遇,说明temp的左边的数都小于等于temp;右边都大于等于temp
int temp = arr[i];
arr[i] = arr[left];
arr[left] = temp;
// temp位置已确定,递归快排剩余的数
quickSort(arr, left, i - 1);
quickSort(arr, j + 1, right);
}
void testQuickSort() {
printf("\n-----quickSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
quickSort(arr, 0, len - 1);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----quickSort-----end\n");
}
堆排序
#include <stdio.h>
//交换
void heapSwap(int arr[], int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 自下而上的建堆方法
void maxHeapify(int arr[], int length) {
int i = length / 2 - 1;
while (i >= 0) {
int left = i * 2 + 1;
int right = i * 2 + 2;
int max; // 左右孩子中最大的数
if (right < length && arr[left] < arr[right]) {
max = right;
} else {
max = left;
}
if (arr[i] < arr[max]) {
// 如果左右孩子中最大的数大于i,则把大的数和i交换
heapSwap(arr, i, max);
}
i--;
}
}
void insertHeap(int arr[], int length) {
for (int i = 1; i < length; i++) {
int currentIndex = i;
int fatherIndex = (i - 1) / 2;
while (currentIndex >= 1 && arr[fatherIndex] < arr[currentIndex]) {
heapSwap(arr, fatherIndex, currentIndex);
currentIndex = fatherIndex;
fatherIndex = (currentIndex - 1) / 2;
}
}
}
void correctHeap(int arr[], int size) {
int index = 0;
while (index * 2 + 1 < size) {
// 至少有一个左孩子
int left = index * 2 + 1; // 左子孩子
int right = index * 2 + 2; // 右子孩子
int max;
if (right < size && arr[left] < arr[right]) {
max = right;
} else {
max = left;
}
if (arr[index] >= arr[max]) {
return;
}
heapSwap(arr, index, max);
index = max;
}
}
/**
* 自下而上的堆排序 建堆复杂度O(n)
* @param arr
* @param length
*/
void heapSort1(int arr[], int length) {
maxHeapify(arr, length);
int size = length;
while (size > 1) {
// 交换堆顶和数组尾部的数、固定最大值
heapSwap(arr, 0, size - 1);
size--;
// 纠正大顶堆
maxHeapify(arr, size);
}
}
/**
* 自上而下、插入法的堆排序 建堆复杂度O(nlogn)
* @param arr
* @param length
*/
void heapSort2(int arr[], int length) {
// 用从上往下遍历插入的方式构造大顶堆
insertHeap(arr, length);
int size = length;
while (size > 1) {
// 交换堆顶和数组尾部的数、固定最大值
heapSwap(arr, 0, size - 1);
size--;
// 纠正大顶堆
correctHeap(arr, size);
}
}
void testHeapSort() {
int arr1[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int arr2[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr1) / sizeof(*arr1);
printf("\n-----heapSort:自下而上-----begin\n");
heapSort1(arr1, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr1[i]);
}
printf("\n-----heapSort:自下而上-----end\n");
printf("\n-----heapSort:自上而下-----begin\n");
heapSort2(arr2, len);
for (i = 0; i < len; i++) {
printf("%d ", arr2[i]);
}
printf("\n-----heapSort:自上而下-----end\n");
}
归并排序
#include <stdio.h>
void merge(int arr[], int low, int mid, int high) {
int length = high - low + 1;
int temp[length];
int i = low;
int j = mid + 1;
int k = 0;
// 把较小的数先移到新数组中
while (i <= mid && j <= high) {
if (arr[i] < arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
// 把左边剩余的数移入数组
while (i <= mid) {
temp[k++] = arr[i++];
}
// 把右边边剩余的数移入数组
while (j <= high) {
temp[k++] = arr[j++];
}
for (i = low; i <= high; i++) {
arr[i] = temp[i - low];
}
}
void mergeSort(int arr[], int low, int high) {
int mid = (low + high) / 2;
if (low < high) {
mergeSort(arr, low, mid);
mergeSort(arr, mid + 1, high);
//左右归并
merge(arr, low, mid, high);
}
}
void testMergeSort() {
printf("\n-----mergeSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
mergeSort(arr, 0, len - 1);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----mergeSort-----end\n");
}
希尔排序
#include <stdio.h>
void shellSort(int arr[], int length) {
int gap;
for (gap = length / 2; gap > 0; gap /= 2) {
// 分组插入排序
for (int i = 0; i < gap; i++) {
for (int j = i + gap; j < length; j += gap) {
int key = arr[j];
int k = j - gap;
while (k >= i && arr[k] > key) {
arr[k + gap] = arr[k];
k -= gap;
}
arr[k + gap] = key;
}
}
}
}
void testShellSort() {
printf("\n-----shellSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
shellSort(arr, len);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----shellSort-----begin\n");
}
基数排序
#include <stdlib.h>
#include <printf.h>
typedef struct RadixNode {
int data;
struct RadixNode *next;
} RadixNode;
struct RadixNode *creatRadixNode(int value) {
RadixNode *node = (RadixNode *) malloc(sizeof(RadixNode));
node->next = NULL;
node->data = value;
return node;
}
#define MOD 10
void radixSort(int arr[], int len, int maxDigit) {
RadixNode **buckets = (RadixNode **) malloc(sizeof(RadixNode *) * MOD);
// 存储链表尾部,用来模拟队列
RadixNode **tailBuckets = (RadixNode **) malloc(sizeof(RadixNode *) * MOD);
for (int i = 0; i < MOD; i++) {
// 创建头结点
struct RadixNode *node = creatRadixNode(-1);
buckets[i] = node;
tailBuckets[i] = node;
}
int index;
RadixNode *head, *next, *temp;
for (int i = 0, radix = 1; i < maxDigit; i++, radix *= MOD) {
for (int j = 0; j < len; j++) {
index = arr[j] / radix % MOD;
// 尾部插入arr[j]
temp = creatRadixNode(arr[j]);
tailBuckets[index]->next = temp;
tailBuckets[index] = temp;
}
int k = 0;
for (int j = 0; j < 10; ++j) {
// 遍历buckets数据,按照先进先出的方式取出链表数据,所以这里应该用队列来实现
RadixNode *p = buckets[j]->next;
while (p) {
arr[k++] = p->data;
temp = p->next;
free(p);
p = temp;
}
// 重置buckets和tailBuckets
buckets[j]->next = NULL;
tailBuckets[j] = buckets[j];
}
}
}
void testRadixSort() {
printf("\n-----radixSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
radixSort(arr, len, 2);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----radixSort-----end\n");
}
桶排序
#include <stdlib.h>
#include <printf.h>
typedef struct BucketNode {
int data;
struct BucketNode *next;
} BucketNode;
struct BucketNode *creatBucketNode(int value) {
BucketNode *node = (BucketNode *) malloc(sizeof(BucketNode));
node->next = NULL;
node->data = value;
return node;
}
/**
* 数组+链表的方式:存放桶数据
* @param arr
* @param length
* @param bucketCounts 桶的数量
*/
void bucketSort(int arr[], int length, int bucketCounts) {
if (length == 0) {
return;
}
int min = arr[0];
int max = arr[0];
for (int i = 1; i < length; i++) {
if (arr[i] < min) {
min = arr[i];
} else if (arr[i] > max) {
max = arr[i];
}
}
// 桶的容量
int bucketSize = (max - min) / bucketCounts + 1;
BucketNode **buckets = (BucketNode **) malloc(sizeof(BucketNode *) * bucketCounts);
for (int i = 0; i < bucketCounts; i++) {
// 创建头结点
buckets[i] = creatBucketNode(-1);
}
for (int i = 0; i < length; i++) {
int index = (arr[i] - min) / bucketSize;
BucketNode *node = buckets[index];
BucketNode *p = node;
while (p->next) {
// 遍历链表,找到要插入的位置
if (p->next->data >= arr[i]) {
break;
}
p = p->next;
}
// 对应桶中插入arr[i]的结点
BucketNode *insertNode = creatBucketNode(arr[i]);
BucketNode *temp = p->next;
p->next = insertNode;
insertNode->next = temp;
}
int i = 0;
for (int j = 0; j < bucketCounts; ++j) {
BucketNode *p = buckets[j];
while (p->next) {
arr[i++] = p->next->data;
p = p->next;
}
}
}
void testBucketSort() {
printf("\n-----bucketSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
bucketSort(arr, len, 4);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----bucketSort-----end\n");
}
计数排序
#include <stdio.h>
#include <stdlib.h>
void countingSort(int arr[], int length, int max) {
int * bucket = (int *) malloc(sizeof(int) * max);
int i, j;
for (i = 0; i < max; i++) {
// 一开始都是0
bucket[i] = 0;
}
for (i = 0; i < length; i++) {
int index = arr[i];
// 用value作为bucket的index
bucket[index] = bucket[index] + 1;
}
for (i = 0, j = 0; i < max; i++) {
int size = bucket[i];
while (size > 0) {
arr[j++] = i;
size--;
}
}
}
void testCountingSort() {
printf("\n-----countingSort-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
countingSort(arr, len, 100);
int i;
for (i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n-----countingSort-----end\n");
}
线性表
数组
#include <printf.h>
#include <stdlib.h>
void testListArray() {
printf("\n-----数组-----begin\n");
int array1[] = {1, 2, 3, 4, 5};
// 动态数组创建
int *array2 = (int *) malloc(sizeof(int) * 10);
array2[1] = 10;
// 二维数组动态创建
int **array3 = (int **) malloc(sizeof(int *) * 10);
for (int i = 0; i < 10; ++i) {
array3[i] = (int *) malloc(sizeof(int) * 5);
}
array3[1][4] = 1;
printf("array[1]=%d array3[1][4]=%d", array1[1], array3[1][4]);
printf("\n-----数组-----end\n");
}
链表
#include <printf.h>
#include <stdlib.h>
// 单链表
typedef struct ListLink {
char data;
struct ListLink *next;
} ListLink;
// 双向链表
typedef struct ListDoubleLink {
char data;
struct ListDoubleLink *next;
struct ListDoubleLink *pre;
} ListDoubleLink;
struct ListLink *creatListLinkNode(char value) {
ListLink *node = (ListLink *) malloc(sizeof(ListLink));
node->next = NULL;
node->data = value;
return node;
}
void testListLink() {
printf("\n-----链表-----begin\n");
ListLink *head = creatListLinkNode('h');
char c = 'a';
// 带头结点的单链表:头结点head的next指向a
// 不带头结点单链表:第一个结点就是a,而不是head
// 带头结点的循环单链表:尾部rear,rear->next=head rear->next->next=a
// 不带头结点循环单链表:尾部rear,rear->next=a
ListLink *p = head;
while (c < 'e') {
p->next = creatListLinkNode(c);
p = p->next;
c++;
}
p = head->next;
// 遍历单链表
while (p) {
printf("%c ", p->data);
p = p->next;
}
// 删除c
p = head;
while (p->next) {
if (p->next->data == 'c') {
break;
}
p = p->next;
}
if (p->next) {
p->next = p->next->next;
}
p = head->next;
printf("\n删除c后的单链表:");
while (p) {
printf("%c ", p->data);
p = p->next;
}
printf("\n-----链表-----begin\n");
}
栈
#include <stdlib.h>
#include <printf.h>
void testListStack() {
printf("\n-----栈-----begin\n");
// 动态数组做栈
char *stack = (char *) malloc(sizeof(char) * 10);
int i = 0;
char c = 'a';
while (c < 'e') {
stack[i++] = c;
c++;
}
printf("出栈:");
while (i > 0) {
// i=0表示栈为空
printf("%c ", stack[--i]);
}
printf("\n-----栈-----end\n");
}
队列
#include <stdlib.h>
#include <printf.h>
void testListQueue() {
printf("\n-----队列-----begin\n");
// 动态数组做队列:无头结点的队列
char *queue = (char *) malloc(sizeof(char) * 10);
int rear = 0, front = 0;
char c = 'a';
while (c < 'e') {
queue[rear++] = c++;
}
printf("出队:");
while (front < rear) {
printf("%c ", queue[front++]);
}
printf("\n-----队列-----end\n");
}
查找
顺序查找
#include <printf.h>
int linearFind(int arr[], int length, int value) {
for (int i = 0; i < length; i++) {
if (arr[i] == value) {
return i;
}
}
return -1;
}
void testFindLinear() {
printf("\n-----find-linear-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\nvalue %d index:%d", arr[3], linearFind(arr, len, arr[3]));
printf("\n-----find-linear-----end\n");
}
二分查找
#include <printf.h>
int binaryFind(int arr[], int length, int value) {
int low = 0, high = length - 1, mid;
if (arr[low] > value || arr[high] < value) {
// 直接返回-1
return -1;
}
while (low <= high && value >= arr[low] && value <= arr[high]) {
mid = low + (high - low) / 2;
if (value == arr[mid]) {
return mid;
}
if (arr[mid] > value) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
void _bubbleSort(int arr[], int len) {
int i, j, temp;
int flag;
for (i = 0; i < len - 1; i++) {
flag = 0;
for (j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = 1;
}
}
if (flag == 0) {
// 说明没有需要交换的数,说明所有的数已排序
return;
}
}
}
void testFindBinary() {
printf("\n-----find-binary-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
// 二分查找 要求已排序
_bubbleSort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\nvalue %d index:%d", arr[3], binaryFind(arr, len, arr[3]));
printf("\nvalue %d index:%d", 21, binaryFind(arr, len, 21));
printf("\n-----find-binary-----end\n");
}
哈希查找
#include <stdlib.h>
#include <printf.h>
#define HASH_SIZE 8
typedef struct HashNode {
// 数组下标,当然也可以再存储value
int index;
int value;
struct HashNode *next;
} HashNode;
struct HashNode *creatHashNode(int index) {
HashNode *node = (HashNode *) malloc(sizeof(HashNode));
node->next = NULL;
node->index = index;
return node;
}
struct HashNode *creatHashNode2(int index, int value) {
HashNode *node = (HashNode *) malloc(sizeof(HashNode));
node->index = index;
node->value = value;
return node;
}
int hashCode(int v) {
return v % 8;
}
HashNode **createHashLinkHead(int arr[], int length) {
HashNode **head = (HashNode **) malloc(sizeof(HashNode *) * HASH_SIZE);
for (int i = 0; i < HASH_SIZE; i++) {
// 带头结点的哈希表
// head[i] = (HashNode *) malloc(sizeof(HashNode));
head[i] = creatHashNode(-1);
}
int hashKey;
HashNode *node;
// 链地址法建表
for (int i = 0; i < length; i++) {
hashKey = hashCode(arr[i]);
node = head[hashKey];
while (node->next) {
// 找到最后一个结点
node = node->next;
}
// 插入到链表最后一个结点
node->next = creatHashNode(i);
}
return head;
}
int findHashLink(HashNode **head, int arr[], int value) {
HashNode *node = head[hashCode(value)]->next;
while (node) {
if (arr[node->index] == value) {
return node->index;
}
node = node->next;
}
return -1;
}
HashNode **createLinearHashTable(int arr[], int length) {
// 这里设置size为16:保证能放下待查找数组每个数
HashNode **table = (HashNode **) malloc(sizeof(HashNode *) * HASH_SIZE * 2);
for (int i = 0; i < HASH_SIZE * 2; i++) {
// 暂定-1为空
table[i] = creatHashNode2(-1, -1);
}
int index;
for (int i = 0; i < length; i++) {
index = hashCode(arr[i]);
while (table[index]->value != -1) {
// 不空,则找到下一个非空位置index
index = (index + 1) % (HASH_SIZE * 2);
}
// 插入到哈希表中
table[index] = creatHashNode2(i, arr[i]);
}
return table;
}
int findHashLinear(HashNode **table, int value) {
int index = hashCode(value);
int i = 0;
while (table[index]->index != -1 && i < HASH_SIZE * 2) {
if (table[index]->value == value) {
return table[index]->index;
}
// 找不到value看下一个位置
index = (index + 1) % (HASH_SIZE * 2);
// i=16时:说明整个哈希表都找了一遍,没发现value
i++;
}
// index对应哈希表为空
return -1;
}
void testFindHash() {
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
printf("\n-----链地址法-----begin\n");
HashNode **linkHead = createHashLinkHead(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\nvalue %d index:%d", arr[3], findHashLink(linkHead, arr, arr[3]));
printf("\nvalue %d index:%d", 21, findHashLink(linkHead, arr, 21));
printf("\n-----链地址法-----end\n");
printf("\n-----线性在探测法-----begin\n");
HashNode **linearTable = createLinearHashTable(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\nvalue %d index:%d", arr[3], findHashLinear(linearTable, arr[3]));
printf("\nvalue %d index:%d", 21, findHashLinear(linearTable, 21));
printf("\n-----线性在探测法-----end\n");
}
插值查找
#include <printf.h>
int interpolationFind(int arr[], int length, int value) {
int low = 0, high = length - 1, mid;
if (arr[low] > value || arr[high] < value) {
// 直接返回-1
return -1;
}
while (low <= high && value >= arr[low] && value <= arr[high]) {
// 计算mid的方式:是唯一和二分查找的区别
int mid = low + (high - low) * (value - arr[low]) / (arr[high] - arr[low]);
if (value == arr[mid]) {
return mid;
}
if (arr[mid] > value) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return -1;
}
void __bubbleSort(int arr[], int len) {
int i, j, temp;
int flag;
for (i = 0; i < len - 1; i++) {
flag = 0;
for (j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = 1;
}
}
if (flag == 0) {
// 说明没有需要交换的数,说明所有的数已排序
return;
}
}
}
void testFindInterpolation() {
printf("\n-----find-interpolation-----begin\n");
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70};
int len = (int) sizeof(arr) / sizeof(*arr);
// 插值查找 要求已排序
__bubbleSort(arr, len);
for (int i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\nvalue %d index:%d", arr[3], interpolationFind(arr, len, arr[3]));
printf("\nvalue %d index:%d", 21, interpolationFind(arr, len, 21));
printf("\n-----find-interpolation-----end\n");
}
KMP算法
#include <stdlib.h>
#include <printf.h>
#include <string.h>
/**
*
* @param pattern 模式串
* @param len
* @return next数组
*/
int *getNext(const char pattern[], int len) {
int *next = (int *) malloc(sizeof(int) * len);
next[0] = -1;
next[1] = 0;
for (int i = 2; i < len; i++) {
int last = next[i - 1];
if (pattern[i - 1] == pattern[last]) {
next[i] = last + 1;
} else {
next[i] = 0;
}
}
return next;
}
/**
*
* @param str 主串
* @param pattern 模式串
* @return {number} 匹配成功时,返回模式串在主串的位置;失败返回-1
*/
int kmp(char str[], char pattern[]) {
int len1 = strlen(str);
int len2 = strlen(pattern);
int *next = getNext(pattern, len2);
int j = 0;
for (int i = 0; i < len1; i++) {
while (j > 0 && str[i] != pattern[j]) {
j = next[j];
}
if (str[i] == pattern[j]) {
j++;
}
if (j == len2) {
return i - len2 + 1;
}
}
return -1;
}
void testKmp() {
printf("\n-----kmp-----begin\n");
char str[] = "abcabcabacba";
char pattern1[] = "abcabb";
char pattern2[] = "bcaba";
printf("主串:%s, 模式串:%s, 匹配结果:%d\n", str, pattern1, kmp(str, pattern1));
printf("主串:%s, 模式串:%s, 匹配结果:%d\n", str, pattern2, kmp(str, pattern2));
printf("\n-----kmp-----begin\n");
}
二叉树
各种遍历递归+非递归实现
#include <stdlib.h>
#include <printf.h>
typedef struct TreeNode {
int value;
char data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
struct TreeNode *creatTree(char value) {
TreeNode *treeNode = (TreeNode *) malloc(sizeof(TreeNode));
treeNode->left = NULL;
treeNode->right = NULL;
treeNode->data = value;
return treeNode;
}
// 先序遍历递归实现
void preTreeOrder1(TreeNode *root) {
if (!root) {
return;
}
printf("%c ", root->data);
preTreeOrder1(root->left);
preTreeOrder1(root->right);
}
// 先序遍历非递归实现
void preTreeOrder2(TreeNode *root) {
if (!root) {
return;
}
struct TreeNode **stack = (struct TreeNode **) malloc(sizeof(struct TreeNode *) * 10);
int i = 0;
stack[i++] = root;
TreeNode *node;
while (i > 0) {
// 栈非空
node = stack[--i];
printf("%c ", node->data);
if (node->right) {
stack[i++] = node->right;
}
if (node->left) {
stack[i++] = node->left;
}
}
}
// 中序遍历递归实现
void midTreeOrder1(TreeNode *root) {
if (!root) {
return;
}
midTreeOrder1(root->left);
printf("%c ", root->data);
midTreeOrder1(root->right);
}
// 中序遍历非递归实现
void midTreeOrder2(TreeNode *root) {
if (!root) {
return;
}
struct TreeNode **stack = (struct TreeNode **) malloc(sizeof(struct TreeNode *) * 10);
int i = 0;
TreeNode *node = root;
while (node || i > 0) {
while (node) {
// 有左节点就进栈
stack[i++] = node;
node = node->left;
}
if (i > 0) {
// 没有左节点就是中间节点、所以访问
node = stack[--i];
printf("%c ", node->data);
// 看是否有右节点
node = node->right;
}
}
}
// 后序遍历递归实现
void lastTreeOrder1(TreeNode *root) {
if (!root) {
return;
}
midTreeOrder1(root->left);
midTreeOrder1(root->right);
printf("%c ", root->data);
}
// 后序遍历非递归实现
void lastTreeOrder2(TreeNode *root) {
if (!root) {
return;
}
struct TreeNode **stack = (struct TreeNode **) malloc(sizeof(struct TreeNode *) * 10);
int i = 0;
TreeNode *node = root;
// 记录上一个访问的节点
TreeNode *preNode;
while (node || i > 0) {
while (node) {
// 有左节点就进栈
stack[i++] = node;
node = node->left;
}
if (i > 0) {
// 取出栈顶,但是不出栈
node = stack[i - 1];
if (!node->right || node->right == preNode) {
// 右节点为空、或者右节点已访问
preNode = stack[--i];
printf("%c ", preNode->data);
node = NULL;
} else {
node = node->right;
}
}
}
}
void levelOrder(struct TreeNode *root) {
if (root == NULL) {
return;
}
// 动态数组做队列
struct TreeNode **queue = (struct TreeNode **) malloc(sizeof(struct TreeNode *) * 10);
int rear = 0, front = 0;
queue[rear++] = root;
struct TreeNode *temp;
while (rear > front) {
temp = queue[front++];
printf("%c", temp->data);
if (temp->left) {
queue[rear++] = temp->left;
}
if (temp->right) {
queue[rear++] = temp->right;
}
}
}
/**
*
* @param root
* @return
*/
int getTreeWpl(struct TreeNode *root) {
if (root == NULL) {
return 0;
}
// 动态数组做队列
struct TreeNode **queue = (struct TreeNode **) malloc(sizeof(struct TreeNode *) * 10);
int rear = 0, front = 0;
queue[rear++] = root;
struct TreeNode *temp;
int wpl = 0;
while (rear > front) {
temp = queue[front++];
if (temp->left || temp->right) {
// 计算非叶结点的权值之和
wpl += temp->value;
}
if (temp->left) {
queue[rear++] = temp->left;
}
if (temp->right) {
queue[rear++] = temp->right;
}
}
return wpl;
}
void testTreeOrder() {
TreeNode *treeNode1 = creatTree('a');
TreeNode *treeNode2 = creatTree('b');
TreeNode *treeNode3 = creatTree('c');
TreeNode *treeNode4 = creatTree('d');
TreeNode *treeNode5 = creatTree('e');
treeNode1->left = treeNode2;
treeNode1->right = treeNode3;
treeNode3->left = treeNode4;
treeNode3->right = treeNode5;
// 哈夫曼树测试数据 wpl=(4+3)*2+6*1=20 or wpl=7+13=20
treeNode4->value = 4;
treeNode5->value = 3;
treeNode3->value = 7;
treeNode2->value = 6;
treeNode1->value = 13;
printf("\n-----先序遍历递归-----begin\n");
preTreeOrder1(treeNode1);
printf("\n-----先序遍历递归-----end\n");
printf("\n-----先序遍历非递归-----begin\n");
preTreeOrder2(treeNode1);
printf("\n-----先序遍历非递归-----end\n");
printf("\n-----中序遍历递归-----begin\n");
midTreeOrder1(treeNode1);
printf("\n-----中序遍历递归-----end\n");
printf("\n-----中序遍历非递归-----begin\n");
midTreeOrder2(treeNode1);
printf("\n-----中序遍历非递归-----end\n");
printf("\n-----后序遍历递归-----begin\n");
lastTreeOrder1(treeNode1);
printf("\n-----后序遍历递归-----end\n");
printf("\n-----后序遍历非递归-----begin\n");
lastTreeOrder2(treeNode1);
printf("\n-----后序遍历非递归-----end\n");
printf("\n-----层序遍历-----begin\n");
levelOrder(treeNode1);
printf("\n-----层序遍历-----end\n");
printf("wpl=%d\n",getTreeWpl(treeNode1));
}
图
数据结构定义:邻接表、邻接矩阵
#include <stdlib.h>
#ifndef STRUCTURE_SOURCE_GRAPH_STRUCTURE
#define STRUCTURE_SOURCE_GRAPH_STRUCTURE
/**
* 邻接表表结点,不带头结点链表
*/
typedef struct ArcNode {
int index; // 顶点序号,从0开始
char value; // 顶点值
int val;
struct ArcNode *next; //邻接链表
} ArcNode;
//邻接表
typedef struct {
ArcNode **adjList; // 邻接表数组
int n, e;//顶点总数 边数
} AdjGraph;
#define VERTEX_SIZE 5
typedef struct GraphVertex {
int index; // 顶点序号,从0开始
char value; // 顶点值
} GraphVertex;
typedef struct {
GraphVertex *vertex[VERTEX_SIZE];
int matrix[VERTEX_SIZE][VERTEX_SIZE];
int vertexNum;
int arcNum;
} MatrixGraph;
struct ArcNode *creatArcNode(char value, int index, const int adjArr[], int adjSize);
AdjGraph *createAdjGraph();
int getRandomRestPoint(AdjGraph *graph, const int *visited);
struct GraphVertex *creatVertex(char value, int index);
// 无向图
MatrixGraph *createMatrixGraph();
// 生成树
MatrixGraph *createSpanningGraph();
#endif
#include "graph-structure.h"
struct ArcNode *creatArcNode(char value, int index, const int adjArr[], int adjSize) {
ArcNode *node = (ArcNode *) malloc(sizeof(ArcNode));
node->value = value;
node->index = index;
ArcNode *temp = node, *p;
for (int i = 0; i < adjSize; ++i) {
p = (ArcNode *) malloc(sizeof(ArcNode));
p->index = adjArr[i];
temp->next = p;
temp = p;
}
temp->next = NULL;
return node;
}
AdjGraph *createAdjGraph() {
struct ArcNode **array = (struct ArcNode **) malloc(sizeof(struct ArcNode *) * 7);
int adj0[] = {1, 2};
int adj1[] = {0, 3, 4};
int adj2[] = {0};
int adj3[] = {1};
int adj4[] = {1};
int adj5[] = {6};
int adj6[] = {5};
ArcNode *node0 = creatArcNode('A', 0, adj0, 2);
ArcNode *node1 = creatArcNode('B', 1, adj1, 3);
ArcNode *node2 = creatArcNode('C', 2, adj2, 1);
ArcNode *node3 = creatArcNode('D', 3, adj3, 1);
ArcNode *node4 = creatArcNode('E', 4, adj4, 1);
ArcNode *node5 = creatArcNode('F', 5, adj5, 1);
ArcNode *node6 = creatArcNode('G', 6, adj6, 1);
array[0] = node0;
array[1] = node1;
array[2] = node2;
array[3] = node3;
array[4] = node4;
array[5] = node5;
array[6] = node6;
AdjGraph *graph = (AdjGraph *) malloc(sizeof(AdjGraph));
graph->n = 7;
graph->e = (2 + 3 + 1 + 1 + 1 + 1 + 1) / 2;
graph->adjList = array;
return graph;
}
// 随机获取一个未访问顶点
int getRandomRestPoint(AdjGraph *graph, const int *visited) {
for (int i = 0; i < graph->n; i++) {
if (visited[i] == 0) {
return i;
}
}
return -1;
}
struct GraphVertex *creatVertex(char value, int index) {
GraphVertex *vertex = (GraphVertex *) malloc(sizeof(GraphVertex));
vertex->index = index;
vertex->value = value;
return vertex;
}
MatrixGraph *createMatrixGraph() {
MatrixGraph *graph = (MatrixGraph *) malloc(sizeof(MatrixGraph));
char a = 'A';
for (int i = 0; i < VERTEX_SIZE; i++) {
graph->vertex[i] = creatVertex(a++, i);
}
int matrix[VERTEX_SIZE][VERTEX_SIZE] = {
{0, 5, 4, 0, 0},
{5, 0, 0, 2, 7},
{4, 0, 0, 0, 0},
{0, 2, 0, 0, 1},
{0, 6, 0, 1, 0},
};
int arcSize = 0;
for (int i = 0; i < VERTEX_SIZE; i++) {
for (int j = i; j < VERTEX_SIZE; j++) {
if (i == j) {
graph->matrix[i][j] = 0;
} else {
if (matrix[i][j] > 0) {
arcSize++;
}
graph->matrix[i][j] = matrix[i][j];
graph->matrix[j][i] = matrix[i][j];
}
}
}
graph->arcNum = arcSize;
graph->vertexNum = VERTEX_SIZE;
return graph;
}
MatrixGraph *createSpanningGraph() {
MatrixGraph *graph = (MatrixGraph *) malloc(sizeof(MatrixGraph));
char a = 'A';
for (int i = 0; i < VERTEX_SIZE; i++) {
graph->vertex[i] = creatVertex(a++, i);
}
int matrix[VERTEX_SIZE][VERTEX_SIZE] = {
{0, 7, 14, 9, 0},
{7, 0, 17, 0, 5},
{14, 17, 0, 4, 15},
{9, 0, 4, 0, 0},
{0, 5, 15, 0, 0},
};
int arcSize = 0;
for (int i = 0; i < VERTEX_SIZE; i++) {
for (int j = i; j < VERTEX_SIZE; j++) {
if (i == j) {
graph->matrix[i][j] = 0;
} else {
if (matrix[i][j] > 0) {
arcSize++;
}
graph->matrix[i][j] = matrix[i][j];
graph->matrix[j][i] = matrix[i][j];
}
}
}
graph->arcNum = arcSize;
graph->vertexNum = VERTEX_SIZE;
return graph;
}
DFS
#include <printf.h>
#include "graph-structure.h"
/**
* 邻接矩阵的dfs
* @param graph 邻接矩阵
* @param i 开始顶点
*/
void dfs(AdjGraph *graph, int i) {
// 记录已访问顶点:0表示未访问,1表示已访问
int *visited = (int *) malloc(sizeof(int) * graph->n);
for (int j = 0; j < graph->n; j++) {
visited[j] = 0;
}
// 待访问顶点栈
int *stack = (int *) malloc(sizeof(int) * graph->n);
int index = 0;
stack[index++] = i;
// 已访问顶点个数
int size = 0;
ArcNode *node;
while (size < graph->n) {
while (index > 0) {
int currentIndex = stack[--index];
node = graph->adjList[currentIndex];
printf("%c ", node->value);
// 访问结点后:更新visited、size
visited[currentIndex] = 1;
size++;
if (size == graph->n) {
return;
}
node = node->next;
while (node) {
// 遍历node相邻顶点,找到未访问的加入栈
if (visited[node->index] == 0) {
stack[index++] = node->index;
}
node = node->next;
}
}
if (size < graph->n) {
// 如果栈为空,但是size<n;说明图G不是连通图,需要在未遍历顶点中随机再找一个顶点进行dfs
stack[index++] = getRandomRestPoint(graph, visited);
}
}
}
void testDfs() {
printf("\n-----dfs-----begin\n");
AdjGraph *graph = createAdjGraph();
printf("起点:%c dfs结果为:", graph->adjList[3]->value);
dfs(graph, 3);
printf("\n起点:%c dfs结果为:", graph->adjList[5]->value);
dfs(graph, 5);
printf("\n-----dfs-----end\n");
}
BFS
#include <printf.h>
#include "graph-structure.h"
/**
* 邻接矩阵的dfs
* @param graph 邻接矩阵
* @param i 开始顶点
*/
void bfs(AdjGraph *graph, int i) {
// 记录已访问顶点:0表示未访问,1表示已访问
int *visited = (int *) malloc(sizeof(int) * graph->n);
for (int j = 0; j < graph->n; j++) {
visited[j] = 0;
}
// 待访问顶点队列
int *queue = (int *) malloc(sizeof(int) * graph->n);
int rear = 0, front = 0;
queue[rear++] = i;
int size = 0;
ArcNode *node;
while (size < graph->n) {
while (front < rear) {
int currentIndex = queue[front++];
node = graph->adjList[currentIndex];
printf("%c ", node->value);
// 访问结点后:更新visited、size
visited[currentIndex] = 1;
size++;
node = node->next;
while (node) {
// 遍历node相邻顶点,找到未访问的加入栈
if (visited[node->index] == 0) {
queue[rear++] = node->index;
}
node = node->next;
}
}
if (size < graph->n) {
// 如果队列为空,但是size<n;说明图G不是连通图,需要在未遍历顶点中随机再找一个顶点进行bfs
queue[rear++] = getRandomRestPoint(graph, visited);
}
}
}
void testBfs() {
printf("\n-----bfs-----begin\n");
AdjGraph *graph = createAdjGraph();
printf("起点:%c bfs结果为:", graph->adjList[3]->value);
bfs(graph, 3);
printf("\n起点:%c bfs结果为:", graph->adjList[5]->value);
bfs(graph, 5);
printf("\n-----dfs-----end\n");
}
迪杰斯特拉算法
#include <printf.h>
#include "graph-structure.h"
// 无限大
#define INF 100
/**
*
* @param graph 邻接矩阵
* @param i 起始点
* @param j 终点
* @return i到j的最短距离
*/
int dijkstra(MatrixGraph *graph, const int i, const int j) {
int n = graph->vertexNum;
// 记录最短距离
int *minDistance = (int *) malloc(sizeof(int) * n);
for (int k = 0; k < n; k++) {
// 一开始除了i都是无穷大
minDistance[k] = k == i ? 0 : INF;
}
// 记录已访问顶点:0表示未访问,1表示已访问
int *visited = (int *) malloc(sizeof(int) * n);
for (int k = 0; k < n; k++) {
visited[k] = 0;
}
visited[i] = 1;
int size = 1;
int current = i;
int minIndex, minDis;
while (size < n) {
for (int k = 0; k < n; k++) {
if (visited[k] == 0 && graph->matrix[current][k] > 0) {
// 获取当前current顶点未访问顶点
int dis = minDistance[current] + graph->matrix[current][k];
if (dis < minDistance[k]) {
// 如果(i到current+current到k)小于minDis:更新minDis
minDistance[k] = dis;
}
}
}
minIndex = -1;
minDis = INF;
for (int k = 0; k < n; k++) {
// 获取当前current顶点未访问顶点, 距离最小的点
if (visited[k] == 0 && minDistance[k] < minDis) {
minDis = minDistance[k];
minIndex = k;
}
}
if (minIndex == j) {
// 如果是目标顶点,直接返回dis
return minDis;
}
if (minIndex == -1) {
// 说明没有相邻顶点了,直接返回无穷大
return INF;
}
visited[minIndex] = 1;
current = minIndex;
size++;
}
}
void testDijkstra() {
printf("\n-----dijkstra-----begin\n");
MatrixGraph *graph = createMatrixGraph();
int i = 0;
int j = 4;
printf("顶点%c到顶点%c最短距离:%d", graph->vertex[i]->value, graph->vertex[j]->value,
dijkstra(graph, i, j));
printf("\n-----dijkstra-----end\n");
}
Floyd算法
// 无限大:表示没有连接路径
#include <printf.h>
#include "graph-structure.h"
#define INF 100
/**
* 邻接矩阵的floyd算法 复杂度O(n³)
* @param graph
* @return
*/
int **floyd(MatrixGraph *graph) {
int n = graph->vertexNum;
int **matrix = (int **) malloc(sizeof(int *) * n);
for (int i = 0; i < n; i++) {
matrix[i] = (int *) malloc(sizeof(int) * n);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (graph->matrix[i][j] == 0) {
matrix[i][j] = INF;
} else {
matrix[i][j] = graph->matrix[i][j];
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
for (int k = 0; k < n; k++) {
if (matrix[i][k] == INF || matrix[k][j] == INF) {
continue;
}
if (matrix[i][k] + matrix[k][j] < matrix[i][j]) {
matrix[i][j] = matrix[i][k] + matrix[k][j];
}
}
}
}
return matrix;
}
void testFloyd() {
printf("\n-----floyd-----begin\n");
MatrixGraph *graph = createMatrixGraph();
int i = 0;
int j = 4;
int **matrix = floyd(graph);
printf("顶点%c到顶点%c最短距离:%d\n", graph->vertex[i]->value, graph->vertex[j]->value,
matrix[i][j]);
printf("顶点%c到顶点%c最短距离:%d", graph->vertex[1]->value, graph->vertex[4]->value,
matrix[1][4]);
printf("\n-----floyd-----end\n");
}
拓扑排序
#include <printf.h>
#include "graph-structure.h"
// 创建一个有向无环图
MatrixGraph *createDagGraph() {
MatrixGraph *graph = (MatrixGraph *) malloc(sizeof(MatrixGraph));
char a = 'A';
for (int i = 0; i < VERTEX_SIZE; i++) {
graph->vertex[i] = creatVertex(a++, i);
}
int matrix[VERTEX_SIZE][VERTEX_SIZE] = {
{0, 1, 1, 1, 0},
{0, 0, 0, 0, 0},
{0, 1, 0, 0, 1},
{0, 0, 0, 0, 1},
{0, 0, 0, 0, 0},
};
for (int i = 0; i < VERTEX_SIZE; i++) {
for (int j = 0; j < VERTEX_SIZE; j++) {
graph->matrix[i][j] = matrix[i][j];
}
}
graph->vertexNum = VERTEX_SIZE;
return graph;
}
// 剩余顶点中找到入度为0的点;-1表示没有入度为0的点
int getIn0(MatrixGraph *graph, const int *visited) {
for (int i = 0; i < graph->vertexNum; i++) {
if (visited[i] == 1) {
continue;
}
int degree = 0;
for (int j = 0; j < graph->vertexNum; j++) {
if (visited[j] == 1) {
continue;
}
degree += graph->matrix[j][i];
if (degree > 0) {
break;
}
}
if (degree == 0) {
return i;
}
}
return -1;
}
/**
* 拓扑排序:输出排序列表
* @param graph
* @return 1表示是有向无环图,支持拓扑排序,0表示不是有向无环图
*/
int dagSort(MatrixGraph *graph) {
int n = graph->vertexNum;
// 记录已访问顶点:0表示未访问,1表示已访问
int *visited = (int *) malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
visited[i] = 0;
}
int size = 0;
printf("拓扑排序:");
while (size < graph->vertexNum) {
int i = getIn0(graph, visited);
if (i == -1) {
return -1;
}
printf("%c ", graph->vertex[i]->value);
visited[i] = 1;
size++;
}
return 1;
}
void testDagSort() {
printf("\n-----拓扑排序-----begin\n");
MatrixGraph *graph = createDagGraph();
int res = dagSort(graph);
printf(" 有向无环图:%d", res);
printf("\n-----拓扑排序-----end\n");
}
Prim算法
#include <printf.h>
#include "graph-structure.h"
#define INF 100
int prim(MatrixGraph *graph) {
int n = graph->vertexNum;
// 记录已访问顶点:0表示未访问,1表示已访问(已固定的顶点)
int *visited = (int *) malloc(sizeof(int) * n);
// 记录每个顶点加入生成树T时在树中的父顶点:用于记录增加的边,如果只是计算最小值 可以不要parent
int *parents = (int *) malloc(sizeof(int) * n);
// 记录每个顶点已查询相邻边的最小值,初始为INF
int *weights = (int *) malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
visited[i] = 0;
parents[i] = -1;
weights[i] = INF;
}
// 加入第一个顶点
int current = 0;
parents[current] = -1;
weights[current] = 0;
visited[current] = 1;
int ast = 0;
int size = 1;
int dis, minDis, minIndex;
while (size < n) {
for (int i = 0; i < n; i++) {
dis = graph->matrix[current][i];
if (visited[i] == 1 || dis == 0) {
// 找相邻且没被访问的
continue;
}
if (dis < weights[i]) {
// 如果dis较小 更新weights和parent
weights[i] = dis;
parents[i] = current;
}
}
// weights中最小的一个顶点固定
minDis = INF;
minIndex = -1;
for (int i = 0; i < n; i++) {
if (visited[i] == 1 || weights[i] == INF) {
continue;
}
if (weights[i] < minDis) {
minDis = weights[i];
minIndex = i;
}
}
if (minIndex != -1) {
// 更新current,接下来看current相邻顶点
current = minIndex;
visited[minIndex] = 1;
ast += minDis;
size++;
} else {
return -1;
}
}
for (int i = 1; i < n; i++) {
int parent = parents[i];
printf("%c%c ", graph->vertex[parent]->value, graph->vertex[i]->value);
}
return ast;
}
void testPrim() {
printf("\n-----prim-----begin\n");
MatrixGraph *graph = createSpanningGraph();
int ast = prim(graph);
printf("\nprim算法最小生成树大小为:%d", ast);
printf("\n-----prim-----end\n");
}
Kruskal算法
#include <printf.h>
#include "graph-structure.h"
/**
* 获取链表尾部结点
* @param nextArray
* @param start
* @return {*}
*/
int findEndNode(const int *nextArray, int start) {
while (nextArray[start] != -1) {
start = nextArray[start];
}
return start;
}
typedef struct {
int i;
int j;
int value;
} Edge;
// 对所有边排序
void bubbleEdgeSort(Edge **edgeList, int len) {
int i, j;
Edge *temp;
int flag;
for (i = 0; i < len - 1; i++) {
flag = 0;
for (j = 0; j < len - 1 - i; j++) {
if (edgeList[j]->value > edgeList[j + 1]->value) {
temp = edgeList[j];
edgeList[j] = edgeList[j + 1];
edgeList[j + 1] = temp;
flag = 1;
}
}
if (flag == 0) {
// 说明没有需要交换的数,说明所有的数已排序
return;
}
}
}
/**
* kruskal算法
* @param matrix
* @return {*[{i,j,weight}]}
*/
int kruskal(MatrixGraph *graph) {
int n = graph->vertexNum;
Edge **edgeList = (struct Edge **) malloc(sizeof(Edge *) * graph->arcNum);
int index = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (graph->matrix[i][j] == 0) {
continue;
}
Edge *edge = (Edge *) malloc(sizeof(Edge));
edge->i = i;
edge->j = j;
edge->value = graph->matrix[i][j];
edgeList[index++] = edge;
}
}
// 1. 对所有边排序
bubbleEdgeSort(edgeList, graph->arcNum);
// 2. 初始化next数组:用于判断是否有环
int *nextArray = (int *) malloc(sizeof(int) * n);
for (int i = 0; i < n; i++) {
nextArray[i] = -1;
}
int nextIndex = 0;
int size = 0;
Edge *edge;
int ast = 0;
while (size < n - 1) {
// 生成树为n-1条边
edge = edgeList[nextIndex++];
int u = findEndNode(nextArray, edge->i);
int v = findEndNode(nextArray, edge->j);
if (u != v) {
// 表示无环
printf("%c%c ", graph->vertex[edge->i]->value, graph->vertex[edge->j]->value);
nextArray[u] = v;
ast += edge->value;
size++;
}
}
return ast;
}
void testKruskal() {
printf("\n-----kruskal-----begin\n");
MatrixGraph *graph = createSpanningGraph();
int res = kruskal(graph);
printf("\nkruskal算法最小生成树大小为:%d", res);
printf("\n-----kruskal-----end\n");
}