【使用场景】
加权非负有向图求某点到其他点的最短距离。
核心思想:
① 找出 当前可达点 与 源节点 距离最短点;
② 以上一步求得的距离最短点,重新计算 当前可达点 与 源节点 的距离;
【代码模板】
/*************************************************
Function: CreateMap
Description: 创建邻接矩阵
Input: dis: 距离关系
disSize: 距离关系个数
n: 节点个数
Output: 邻接矩阵
Others: 无
*************************************************/
int **CreateMap(int **dis, int disSize, int n)
{
int **map;
map = (int **)malloc(sizeof(int *) * (n + 1));
for (int i = 0; i < (n + 1); i++) {
map[i] = (int *)malloc(sizeof(int) * (n + 1));
memset(map[i], 0x1f, sizeof(int) * (n + 1)); // 初始化 非联通点 为极大值
}
for (int i = 0; i < disSize; i++) {
map[dis[i][0]][dis[i][1]] = map[dis[i][2]]; // 初始化联通点距离
}
return map;
}
/*************************************************
Function: Dijkstra
Description: Dijkstra算法
Input: srcNode: 源节点
n: 节点个数
map: 邻接矩阵
Output: 距离矩阵
Others: 无
*************************************************/
int *Dijkstra(int **map, int n, int srcNode)
{
int node;
int minDis;
int *dis;
int *visit;
bool flag = false;
dis = (int *)malloc(sizeof(int) * (n + 1));
visit = (int *)malloc(sizeof(int) * (n + 1));
memset(dis, 0x1f, sizeof(int) * (n + 1));
memset(visit, 0, sizeof(int) * (n + 1));
node = srcNode;
dis[node] = 0;
for (int i = 0; i <= n; i++) {
minDis = 65535;
// 寻找距离最小的点
for (int j = 0; j <= n; j++) {
if (visit[j] == 0 && dis[j] < minDis) {
minDis = dis[j];
node = j;
}
}
// 标识已找到最小距离
visit[node] = 1;
// 基于当前最小点,刷新所有可达点距离
for (int j = 0; j <= n; j++) {
if (visit[j] == 0 && dis[j] > dis[node] + map[node][j]) {
dis[j] = dis[node] + map[node][j];
}
}
}
return dis;
}
【练习题】
Leetcode-743:网络延迟时间链接: link.
———————————————————————————————————————————————————————
【使用场景】
DFS、BFS图遍历时,稀疏邻接矩阵,使用邻接矩阵,空间复杂度过高,创建邻接关系图。
【代码模板】
/*************************************************
Function: CreateMap
Description: 创建邻接表(有向)
Input: sideNum: 边数
sideArr: 邻接关系
Output: 邻接矩阵
Others: 无
*************************************************/
#define MAX_NODE_NUM 1001
typedef struct NodeStru {
int pos;
int stepLen;
struct NodeStru *next;
} NodeStru;
typedef struct LinkTab {
int nodeNum;
NodeStru *firstNode;
} LinkTab;
int g_nodeNum;
LinkTab g_linkTab[MAX_NODE_NUM];
void CreateLinkTab(int sideNum, int **sideArr)
{
NodeStru *tmpNode;
/* 初始化所有节点边表 */
for (int i = 0; i < g_nodeNum; i++) {
g_linkTab[i].nodeNum = 0;
g_linkTab[i].firstNode = NULL;
}
/* 加入边表 */
for (int i = 0; i < sideNum; i++) {
tmpNode = (NodeStru *)malloc(sizeof(NodeStru));
tmpNode->pos = sideArr[i][1];
tmpNode->stepLen = sideArr[i][2];
tmpNode->next = g_linkTab[sideArr[i][0]].firstNode;
g_linkTab[sideArr[i][0]].firstNode = tmpNode;
g_linkTab[sideArr[i][0]].nodeNum++;
}
}
———————————————————————————————————————————————————————
【使用场景】
快速排序,char / int / struct / 二级指针数组。
【代码模板】
/*************************************************
Function: qsort
Description: 快速排序,char / int / struct / 二级指针数组
Input: 无序数组
Output: 有序数组
Others: 无
*************************************************/
int CompareOneCh(const void *a, const void *b)
{
char *ap = (char *)a;
char *bp = (char *)b;
return *ap - *bp;
}
qsort(oneCh, 4, sizeof(char), CompareOneCh);
int CompareOneInt(const void *a, const void *b)
{
int *ap = (int *)a;
int *bp = (int *)b;
return *ap - *bp;
}
qsort(oneInt, 5, sizeof(int), CompareOneInt);
int CompareTwoCh(const void *a, const void *b)
{
return strcmp((char *)a, (char *)b);
}
qsort(twoCh, 5, sizeof(twoCh[0]), CompareTwoCh);
int CompareTwoChPst(const void *a, const void *b)
{
char *ap = *(char **)a;
char *bp = *(char **)b;
return strcmp(ap, bp);
}
qsort(twoChPst, 5, sizeof(twoChPst[0]), CompareTwoChPst);
int CompareTwoInt(const void *a, const void *b)
{
return ((int *)a)[1] - ((int *)b)[1];
}
qsort(twoInt, 5, sizeof(twoInt[0]), CompareTwoInt);
int CompareTwoIntPst(const void *a, const void *b)
{
int *ap = *(int **)a;
int *bp = *(int **)b;
return ap[1] - bp[1];
}
qsort(twoIntPst, 5, sizeof(twoIntPst[0]), CompareTwoIntPst);
typedef struct {
int val1;
int val2;
char str[5];
} Test;
int CompareStru(const void *a, const void *b)
{
Test *ap = (Test *)a;
Test *bp = (Test *)b;
if (ap->val1 != bp->val1) {
return ap->val1 - bp->val1;
} else if (ap->val2 != bp->val2) {
return ap->val2 - bp->val2;
} else {
return strcmp(ap->str, bp->str);
}
}
qsort(stru, 5, sizeof(stru[0]), CompareStru);
———————————————————————————————————————————————————————
【使用场景】
图遍历。
【代码模板】
/*************************************************
Function: TraverseBfs
Description: BFS
Input:
Output:
Others: 无
*************************************************/
int TraverseBfs(char **wordList, int wordListSize, char *beginWord, char *endWord)
{
int sum = 0;
int seq = 0;
int lay = 1;
EnQueue(seq);
while (!IsEmpty()) {
sum = g_size;
lay++;
for (int i = 0; i < sum; i++) {
seq = DeQueue();
for (int j = 0; j < wordListSize; j++) {
if (g_visit[j] == 0 && IsValid()) {
EnQueue(j);
g_visit[j] = 1;
if (IsDst()) {
return lay;
}
}
}
}
}
return 0;
}
———————————————————————————————————————————————————————
【使用场景】
归并。
核心思想:
① 初始化每个点的父节点为其本身;
② 找出 当前点 的 根 ;
③ 刷新 当前点 的所有父节点为 根;
④ 合并:如果两个根不相等,其中一个根指向另一个根;
【代码模板】
#define MAX_NODE_NUM 10001
int g_pre[MAX_NODE_NUM];
void Init()
{
for (int i = 0; i < MAX_NODE_NUM; i++) {
g_pre[i] = i;
}
}
int UnionSearch(int root)
{
int son, tmp;
son = root;
while (g_pre[root] != root) {
root = g_pre[root];
}
while (son != root) {
tmp = g_pre[son];
g_pre[son] = root;
son = tmp;
}
return root;
}
bool Join(int a, int b)
{
int rootA, rootB;
rootA = UnionSearch(a);
rootB = UnionSearch(b);
if (rootA != rootB) {
g_pre[rootA] = rootB;
return false;
}
return true;
}
———————————————————————————————————————————————————————
【使用场景】
【代码模板】
/*************************************************
Function: BinarySearch
Description: 二分查找
Input:
Output:
Others: 无
*************************************************/
int BinarySearch(int *array, int size, int key)
{
int low = 0;
int mid = 0;
int high = size - 1;
while (low <= high) {
mid = low + (high - low) / 2;
if (array[mid] > key) {
high = mid - 1;
} else if (array[mid] < key) {
low = mid + 1;
} else {
// same fst
while (array[mid] == array[mid - 1]) {
mid--;
}
return mid;
}
}
return -1;
}
———————————————————————————————————————————————————————
【使用场景】
【代码模板】
/*************************************************
Function: AddNode
Description: 平衡二叉树添加节点
Input:
Output:
Others: 无
*************************************************/
NodeStru *AddNode(NodeStru *root, int val)
{
if (root == NULL) {
root = (NodeStru *)malloc(sizeof(NodeStru));
memset(root, 0, sizeof(NodeStru));
root->val = val;
return root;
}
if (root->val >= val ) {
root->smartCnt++;
root->left = AddNode(root->left, val);
} else {
g_maxValue += root->smartCnt + 1;
root->right = AddNode(root->right, val);
}
}
———————————————————————————————————————————————————————
【使用场景】
核心思想:
① 初始化栈为0;
② 当前点 不满足单调特性,入栈 ;
③ 当前点 不满足特性,出栈,知道满足位置,压入栈;
【代码模板】
/*************************************************
Function: MonoStack
Description: 单调栈
Input:
Output:
Others: 无
*************************************************/
void MonoStack(int* T, int TSize, int *seqList)
{
for (int i = 0; i < TSize; i++) {
while (T[i] > T[g_stack[g_top]] && !IsEmpty()) {
seqList[g_stack[g_top]] = i - g_stack[g_top];
Pop();
}
Push(i);
}
}
———————————————————————————————————————————————————————
【使用场景】
排列
【代码模板】
void SwapElem(char *s, int posA, int posB)
{
char ch = s[posA];
s[posA] = s[posB];
s[posB] = ch;
}
bool IsValidElem(char *s, char ch)
{
if (s[ch - 'a'] == 0) {
return true;
}
return false;
}
void TraverseDfs(char **rst, char *s, int curSeq, int len)
{
char usedElem[MAX_ELEM_NUM];
memset(usedElem, 0, MAX_ELEM_NUM);
if (curSeq == len - 1) {
strcpy(rst[g_rstNum], s);
printf("%s\n", s);
g_rstNum++;
return;
}
for (int i = curSeq; i < len; i++) {
if (!IsValidElem(usedElem, s[i])) {
continue;
}
usedElem[s[i] - 'a'] = 1;
SwapElem(s, curSeq, i);
TraverseDfs(rst, s, curSeq + 1, len);
SwapElem(s, curSeq, i);
}
}
———————————————————————————————————————————————————————
【使用场景】
数据结构
【代码模板】
typedef struct NODE {
char data;
struct NODE *pNext;
} NODE, *LINK_NODE_STRU;
LINK_NODE_STRU CreateLinkList(int len)
{
LINK_NODE_STRU pHead = NULL;
LINK_NODE_STRU pNew = NULL;
LINK_NODE_STRU pTail = NULL;
pHead = (LINK_NODE_STRU)malloc(sizeof(NODE));
if (pHead == NULL) {
// return -1;
}
pHead->data = 0;
pHead->pNext = NULL;
pTail = pHead;
for (int i = 0; i < len; i++) {
pNew = (LINK_NODE_STRU)malloc(sizeof(NODE));
if (pNew == NULL) {
// return -1;
}
pNew->data = g_data[i];
pNew->pNext = NULL;
pTail->pNext = pNew;
pTail = pNew;
}
return pHead;
}
void PrintLinkList(LINK_NODE_STRU pHead)
{
LINK_NODE_STRU pCur;
pCur = pHead->pNext;
printf("\n");
while (pCur != NULL) {
printf("%c", pCur->data);
pCur = pCur->pNext;
}
}
int InsertLinkList(LINK_NODE_STRU pHead, char data)
{
// 升序插入
LINK_NODE_STRU pCur;
LINK_NODE_STRU pLast;
LINK_NODE_STRU pNew;
pNew = (LINK_NODE_STRU)malloc(sizeof(NODE));
if (pNew == NULL) {
return -1;
}
pNew->data = data;
pNew->pNext = NULL;
pCur = pHead->pNext;
// head
if (pCur->data >= data) {
pNew->pNext = pCur;
pHead->pNext = pNew;
return 0;
}
// mid
while ((pCur->data < data) && ((pCur->pNext) != NULL)) {
pLast = pCur;
pCur = pCur->pNext;
}
// rear
if ((pCur->data) < data) {
pCur->pNext = pNew;
pNew->pNext = NULL;
return 0;
}
pLast->pNext = pNew;
pNew->pNext = pCur;
return 0;
}
int DeleteElem(LINK_NODE_STRU pHead, int num)
{
int curNum = 0;
P_LINKLIST_STRU pCur;
P_LINKLIST_STRU pLast;
pLast = pHead;
pCur = pHead;
while (pCur->pNext != NULL) {
if (curNum == num) {
pLast->pNext = pCur->pNext;
free(pCur);
return 0;
}
pLast = pCur;
pCur = pCur->pNext;
curNum++;
}
if ((pCur->pNext == NULL) && (curNum == num)) {
pLast->pNext = NULL;
free(pCur);
return 0;
}
return -1;
}
int DeleteLinkList(LINK_NODE_STRU pHead, char data)
{
LINK_NODE_STRU pCur;
LINK_NODE_STRU pLast;
pLast = pHead;
pCur = pHead->pNext;
while (pCur->pNext != NULL) {
if (pCur->data == data) {
pLast->pNext = pCur->pNext;
free(pCur);
pCur = pLast;
}
pLast = pCur;
pCur = pCur->pNext;
}
//del rear
if (pCur -> data == data) {
pLast->pNext = NULL;
free(pCur);
}
return 0;
}
———————————————————————————————————————————————————————
【使用场景】
【代码模板】
/*************************************************
Function: SlideWindow
Description: 滑动窗口
Input:
Output:
Others: 无
*************************************************/
int SlideWindow(int s, int *nums, int numsSize)
{
int len;
int minLen = INT_MAX;
int leftSeq = 0;
int rightSeq = 0;
long sum = 0;
while (rightSeq < numsSize) {
sum += nums[rightSeq]; // 右边界移动 找第一个满足条件
while (sum >= s && leftSeq <= rightSeq) {
len = rightSeq - leftSeq + 1;
if (len < minLen) {
minLen = len;
}
sum -= nums[leftSeq];
leftSeq++; // 左边界移动 找第一个不满足条件
}
rightSeq++;
}
return minLen;
}
———————————————————————————————————————————————————————
【使用场景】
查找、排序
【代码模板】
haxi,1=
typedef struct {
int row;
int col;
}Pos;
typedef struct HashStru {
Pos key;
int val;
UT_hash_handle hh;
}Hash;
Hash *g_hash = NULL;
void AddElem(Pos key, int val)
{
Hash *hash;
HASH_FIND(hh, g_hash, &key, sizeof(Pos), hash);
if (hash==NULL) {
hash = (Hash *)malloc(sizeof(Hash));
hash->key.row = key.row;
hash->key.col = key.col;
HASH_ADD(hh, g_hash, key, sizeof(Pos), hash);
}
hash->val = val;
}
Hash *FindElem(Pos key)
{
Hash *hash;
HASH_FIND(hh, g_hash, &key, sizeof(Pos), hash);
return hash;
}
void DelHash()
{
Hash *hash, *tmp;
HASH_ITER(hh, g_hash, hash, tmp) {
HASH_DEL(g_hash, hash);
free(hash);
}
}
haxi,2=
typedef struct myhash {
int key;
int val;
UT_hash_handle hh;
}hash;
hash *g_hash = NULL;
void AddHash(int a)
{
hash *s;
// int key = (int)a; //a char
HASH_FIND_INT(g_hash, &a, s);
if (s) {
printf("%d\n", s->val);
} else {
s = (hash *)malloc(sizeof(hash));
s->key = a;
s->val = 1;
HASH_ADD_INT(g_hash, key, s);
}
}
void UpdateHash(int key, int newval)
{
hash *s;
// int key = (int)a; //a char
HASH_FIND_INT(g_hash, &key, s);
if (s) {
printf("%d\n", s->val);
s->val = newval;
} else {
s = (hash *)malloc(sizeof(hash));
s->key = key;
s->val = newval;
HASH_ADD_INT(g_hash, key, s);
}
}
void DelOneKey(int key)
{
hash *s;
// int key = (int)a; //a char
HASH_FIND_INT(g_hash, &key, s);
if (s) {
HASH_DEL(g_hash, s);
free(s);
}
}
void DelHash()
{
hash *s, *tmp;
HASH_ITER(hh, g_hash, s, tmp) {
HASH_DEL(g_hash, s);
free(s);
}
}
void IterHash()
{
hash *s, *tmp;
HASH_ITER(hh, g_hash, s, tmp) {
printf("key(%d) val(%d) ", s->key, s->val);
}
printf("\n**************\n");
}
int Compare(hash *a, hash *b)
{
return (a->key - b->key);
}
void SortHash()
{
HASH_SORT(g_hash, cmp);
}
———————————————————————————————————————————————————————
【ctype.h】
int isalnum(int ch) int isalpha(int ch) int isdigit(int ch)
int islower(int ch) int isupper(int ch) int isspace(int ch)
int isxdigit(int ch) int tolower(int ch) int toupper(int ch)
int sscanf(const char *buffer, const char *format, …)
int sprintf(char *buffer, const char *format, …)