刷题算法归档

目录

  • Djkstra(迪杰斯特拉)
  • 邻接表
  • qsort
  • 广度优先(BFS)
  • 并查集
  • 二分查找
  • 平衡二叉树
  • 单调栈
  • 全排列
  • 链表
  • 滑动窗口
  • 哈希
  • 常用字符处理函数

Djkstra(迪杰斯特拉)

【使用场景】
加权非负有向图求某点到其他点的最短距离。
核心思想:
① 找出 当前可达点源节点 距离最短点;
② 以上一步求得的距离最短点,重新计算 当前可达点源节点 的距离;

【代码模板】

/*************************************************
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++;
    }
}

———————————————————————————————————————————————————————

qsort

【使用场景】
快速排序,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);

———————————————————————————————————————————————————————

广度优先(BFS)

【使用场景】
图遍历。

【代码模板】

/*************************************************
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,)

你可能感兴趣的:(刷题)