0.0 编码基础模板

1. 链表模板

c 复制代码
truct ListNode {
	int val;
	struct ListNode *next;
};
typedef struct MyLinkedList_t {
	int val;
	struct MyLinkedList_t *next;
} MyLinkedList;
void myLinkedListAddAtIndex(MyLinkedList *obj, int index, int val);
MyLinkedList *myLinkedListCreate()
{
	// 在链表的第一个结点之前会额外增设一个结点,头结点
	MyLinkedList *dummyHead = (MyLinkedList *)malloc(sizeof(MyLinkedList));
	if (dummyHead == NULL) {
		return NULL;
	}
	dummyHead->next = NULL;
	dummyHead->val = 0; // 头结点的val用来指示链表长度
	return dummyHead;
}
// 从头节点开始遍历,找到index对应的值并返回
int myLinkedListGet(MyLinkedList *obj, int index)
{
	int cnt = 0;
	MyLinkedList *tmp = obj->next;
	while (tmp != NULL) {
		if (index == cnt) {
			return tmp->val;
		}
		tmp = tmp->next;
		cnt++;
	}
	return -1;
}
void myLinkedListAddAtHead(MyLinkedList *obj, int val)
{
	myLinkedListAddAtIndex(obj, 0, val);
}
void myLinkedListAddAtTail(MyLinkedList *obj, int val)
{
	myLinkedListAddAtIndex(obj, obj->val, val);
}
// 插入节点
void myLinkedListAddAtIndex(MyLinkedList *obj, int index, int val)
{
	int cnt = 0;
	if (index > obj->val) {
		// 1.索引大于长度
		return;
	}
	// 2.索引插入节点
	MyLinkedList *tmp = obj;
	MyLinkedList *newNode = (MyLinkedList *)malloc(sizeof(MyLinkedList));
	newNode->val = val;
	while (tmp != NULL) {
		if (cnt == index) {
			break;
		}
		tmp = tmp->next;
		cnt++;
	}
	newNode->next = tmp->next;
	tmp->next = newNode;
	obj->val++; // 记录链表长度
	return;
}
// 删除节点
void myLinkedListDeleteAtIndex(MyLinkedList *obj, int index)
{
	MyLinkedList *node = NULL;
	MyLinkedList *tmp = obj;
	int cnt = 0;
	if (index >= obj->val) {
		return; // 下标无效
	}
	while (tmp != NULL) {
		if (cnt == index) {
			break;
		}
		cnt++;
		tmp = tmp->next;
	}
	if (tmp->next == NULL) { // 删除的是最后的NULL,直接返回,手法
		return;
	}
	obj->val--;
	node = tmp->next; // tmp->next为要删除的节点,tmp->next = tmp->next->next
	tmp->next = node->next; // 这么操作是因为free(node)
	free(node);
}
void myLinkedListFree(MyLinkedList *obj) {
	MyLinkedList *tmp = obj;
	MyLinkedList *freeNode;
	while (tmp != NULL) {  // 释放头结点->首元结点内的
		freeNode = tmp;
		tmp = tmp->next;
		freeNode->next = NULL;
		freeNode->val = 0;
		free(freeNode);
	}
}
int main()
{
	int ret = 0;
	MyLinkedList* obj = myLinkedListCreate();
	myLinkedListAddAtHead(obj, 1);
	myLinkedListAddAtTail(obj, 3);
	myLinkedListAddAtIndex(obj, 1, 2);
	ret = myLinkedListGet(obj, 1);
	myLinkedListDeleteAtIndex(obj, 1);
	ret = myLinkedListGet(obj, 1);
	ret = myLinkedListGet(obj, 3);
	myLinkedListDeleteAtIndex(obj, 3);
	myLinkedListDeleteAtIndex(obj, 3);
	ret = myLinkedListGet(obj, 0);
	myLinkedListDeleteAtIndex(obj, 0);
	ret = myLinkedListGet(obj, 0);
	return 0;
}

2. 队列实现模板

c 复制代码
#define MAX_NUN     1024
typedef struct {
	int head;
	int tail;
	int size; // 计算队列元素个数
	int data[MAX_NUN];
} Queue_t;
Queue_t *QueueCreate(int size)
{
	Queue_t *queue = (Queue_t *)malloc(sizeof(Queue_t));
	queue->tail = 0;
	queue->head = 0;
	queue->size = size;
	memset(queue->data, 0, sizeof(int) * (MAX_NUN));
	return queue;
}
bool QueuePush(Queue_t *queue, int value)
{
	if (QueueIsFull(queue)) {
		return false;
	}
	queue->data[queue->tail] = value;  // 先入队
	queue->tail = (queue->tail + 1) % queue->size; // tail再移动,队尾元素为tail-1.
	return true;
}
bool QueuePop(Queue_t *queue, int *value)
{
	if (QueueIsEmpty(queue)) {
		return false;
	}
	*value = queue->data[queue->head];
	queue->head = (queue->head + 1) % queue->size;
	return true;
}
bool QueueIsEmpty(Queue_t *queue)
{
	return (queue->head == queue->tail);
}
bool QueueIsFull(Queue_t *queue)
{
	return (((queue->tail + 1) % queue->size) == queue->head);
}
int QueueFront(Queue_t *queue)
{
	if (QueueIsEmpty(queue)) {
		return -1;
	}
	return queue->data[queue->head];
}
int QueueTail(Queue_t *queue)
{
	if (QueueIsEmpty(queue)) {
		return -1;
	}
	return queue->data[(queue->tail - 1 + queue->size) % queue->size];
}
void QueueFree(Queue_t *queue)
{
	free(queue);
	queue = NULL;
}

3. 单调栈

c 复制代码
int stack[size];
//此处一般需要给数组最后添加结束标志符,具体下面例题会有详细讲解
for (遍历这个数组)
{
	if (栈空 || 栈顶元素大于等于当前比较元素)
	{
		入栈;
	} else
	{
		while (栈不为空 && 栈顶元素小于当前元素)
		{
			栈顶元素出栈;
			更新结果;
		}
		当前数据入栈;
	}
}

什么是单调栈?

从名字上就听的出来,单调栈中存放的数据应该是有序的,所以单调栈也分为单调递增栈和单调递减栈

单调递增栈:单调递增栈就是从栈底到栈顶数据是从大到小

单调递减栈:单调递减栈就是从栈底到栈顶数据是从小到大

递增栈 :

pointer: bottom top

Index: 0 1 2 3

val: 60 20 20 10

栈底 - 《《《《《《《 - 栈顶(自顶向下为递增)


c 复制代码
#define NUM_SIZE 10001
void GetNext(int *num, int size, int *res)
{
	int top = 0;
	int *stack = (int *)malloc(sizeof(int) * size);
	memset(stack, 0, sizeof(int) * size);
	for (int i = 0; i < size; i++) {
		if ((top == 0) || (num[i] <= stack[top - 1])) {
			stack[top] = num[i];
			top++;
		} else {
			while ((top > 0) && (num[i] > stack[top - 1])) { // 如果此时比较元素大于栈顶元素,则栈顶元素出栈.
				res[stack[top - 1]] = num[i];                 // 将找到的元素作为map存下来.
				top--;
			}
			stack[top] = num[i];
			top++;
		}
	}
	// 处理此时还未出栈的元素,都是不存在下一个更大元素的,赋值为-1。
	while (top > 0) {
		res[stack[top - 1]] = -1;
		top--;
	}
	free(stack);
}

4. 字符串

判断字符串是否为数字(包括正负数)

c 复制代码
if (sscanf(token, "%d", &num) == 1) { // 判断是否为数字的方法,包括正负数
    *** = num; // 使用num
} 
c 复制代码
// 使用正则表达式,识别字符串
sscanf(logs[i], "%d:%[a-z]:%d", &idx, type, &timestamp); // 拆分字符串
  1. 常见用法。
      char buf[512] ={0} ;
      sscanf("123456 ", "%s", buf);
      printf("%s/n", buf);
      结果为:123456
  2. 取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
      sscanf("123456 ", "%4s", buf);
      printf("%s/n", buf);
      结果为:1234
  3. 取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
      sscanf("123456 abcdedf", "%[^ ]", buf);
      printf("%s/n", buf);
      结果为:123456
  4. 取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
      sscanf("123456abcdedfBCDEF", "%[1-9a-z]", buf);
      printf("%s/n", buf);
      结果为:123456abcdedf
  5. 取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
      sscanf("123456abcdedfBCDEF", "%[^A-Z]", buf);
      printf("%s/n", buf);
      结果为:123456abcdedf
    6、给定一个字符串iios/12DDWDFF@122,获取 / 和 @ 之间的字符串,先将 "iios/"过滤掉,再将非'@'的一串内容送到buf中
      sscanf("iios/12DDWDFF@122", "%*[/]/%[@]", buf);
      printf("%s/n", buf);
      结果为:12DDWDFF

DFS模板

c 复制代码
void dfs(参数) {
    if (终止条件) {
        存放结果;
        return;
    }
    for (选择:本节点所连接的其他节点) {
        处理节点;
        dfs(图,选择的节点); // 递归
        回溯,撤销处理结果
    }
}

BFS模板

c 复制代码
nt dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 表示四个方向
// grid 是地图,也就是一个二维数组
// visited标记访问过的节点,不要重复访问
// x,y 表示开始搜索节点的下标
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
    queue<pair<int, int>> que; // 定义队列
    que.push({x, y}); // 起始节点加入队列
    visited[x][y] = true; // 只要加入队列,立刻标记为访问过的节点
    while(!que.empty()) { // 开始遍历队列里的元素
        pair<int ,int> cur = que.front(); que.pop(); // 从队列取元素
        int curx = cur.first;
        int cury = cur.second; // 当前节点坐标
        for (int i = 0; i < 4; i++) { // 开始想当前节点的四个方向左右上下去遍历
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1]; // 获取周边四个方向的坐标
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 坐标越界了,直接跳过
            if (visited[nextx][nexty] == 0) { // 如果节点没被访问过
                que.push({nextx, nexty});  // 队列添加该节点为下一轮要遍历的节点
                visited[nextx][nexty] = true; // 只要加入队列立刻标记,避免重复访问
            }
        }
    }
}
相关推荐
共享家95272 小时前
Leetcode刷题
算法·leetcode·职场和发展
simon_skywalker2 小时前
第7章 n步时序差分 n步时序差分预测
人工智能·算法·强化学习
Terio_my3 小时前
Spring Boot 热部署配置与自定义排除项
java·spring boot·后端
山,离天三尺三3 小时前
基于LINUX平台使用C语言实现MQTT协议连接华为云平台(IOT)(网络编程)
linux·c语言·开发语言·网络·物联网·算法·华为云
flashlight_hi3 小时前
LeetCode 分类刷题:74. 搜索二维矩阵
python·算法·leetcode·矩阵
小年糕是糕手3 小时前
【数据结构】算法复杂度
c语言·开发语言·数据结构·学习·算法·leetcode·排序算法
JAVA学习通4 小时前
微服务项目->在线oj系统(Java-Spring)--C端用户(超详细)
java·开发语言·spring
计算机毕业设计小帅4 小时前
【2026计算机毕业设计】基于jsp的毕业论文管理系统
java·开发语言·毕业设计·课程设计