数据结构(Day19)

news2024/9/23 21:59:15

一、学习内容

  1. 单链表

    1. 头删

        1. int front_dele(Plink L)
          {
          	if(L==NULL||L->len==0)
          	{
          		printf("头删失败\n");
          		return -1;
          	}
          	Plink Q = L->next;//保留要删除的1号节点
          	L->next = L->next->next;
          	L->len--;
          	free(Q);//释放空间
          	Q=NULL;
          	return 0;
          }
          

    2. 尾删

        1. int rear_dele(Plink L)
          {
          	if(empty(L))
          	{
          		printf("尾删失败\n");
          		return -1;
          	}
          	int i;
          	Plink t = L;
          	for(i = 0;i<L->len-1;i++)//将t指向要删除节点的前驱
          	{
          		t = t->next;
          	}
          	Plink Q = t->next;//保留要删除的节点
          	t->next = NULL;
          	L->len--;
          	free(Q);
          	Q=NULL;
          	return 0;
          }

    3. 按值删除

        1. int value_dele(Plink L,int key)
          {
          	if(empty(L))
          	{
          		printf("按值删除失败\n");
          		return -1;
          	}
          	int i,flag=0;
          	Plink t = L;//指向头节点
          	for(i = 0;i<L->len;i++)//遍历整个单链表查找该值是否存在
          	{
          		if(key==t->next->data)
          		{
          			flag=1;
          			break;//退出循环t指向查找到的节点前驱
          		}
          		t  = t->next;
          	}
          	if(flag==0)
          	{
          		printf("没有该值,删除失败\n");
          	}
          	else
          	{
          		Plink Q = t->next;//保留要删除的节点
          		t->next = t->next->next;
          		free(Q);
          		Q=NULL;
          		L->len--;
          	}
          	return 0;

    4. 按值修改

      1. int value_change(Plink L,int key,int e)
        {
        	if(empty(L))
        	{
        		printf("按值修改失败\n");
        		return -1;
        	}
        	int i,flag=0;
        	Plink t = L;//指向头节点
        	for(i = 0;i<L->len;i++)//遍历整个单链表查找该值是否存在
        	{
        		if(key==t->data)
        		{
        			flag=1;
        			break;//退出循环t指向查找到的节点
        		}
        		t  = t->next;
        	}
        	if(flag==0)
        	{
        		printf("没有该值,修改失败\n");
        	}
        	else
        	{
        		t->data = e;
        	}
        	return 0;
        }
        
        

    5. 按值查找返回地址

      1. Plink value_find(Plink L,int key)
        {
        	int i;
        	Plink t = L;
        	for(i = 0;i<L->len;i++)
        	{
        		t = t->next;
        		if(t->data==key)
        		{
        			return t;
        		}
        	}
        	return NULL;
        }

    6. 链表逆置

      1. int link_re(Plink L)
        {
        	Plink Q,t;
        	Q = L->next;
        	t = Q->next;
        	while(t!=NULL)
        	{
        		Q->next = t->next;
        		t->next = L->next;
        		L->next = t;
        
        		t = Q->next;
        	}
        	return 0;
        }

    7. 排序

      1. 
        int popul_sort(Plink L)
        {
        	int temp,i;
        	Plink j;
        	for(i = 1;i<L->len;i++)
        	{
        		for(j = L->next;j->next!=NULL;j=j->next)
        		{
        			if(j->data>j->next->data)
        			{
        				temp = j->data;
        				j->data = j->next->data;
        				j->next->data = temp;
        			}
        		}
        	}
        	return 0;
        }

    8. 去重

        1. int node_dele(Plink L,Plink j)
          {
          	Plink Q = j->next;
          	j->next = j->next->next;
          	free(Q);
          	Q=NULL;
          	L->len--;
          }
          int Dedup(Plink L)
          {
          	Plink i,j,Q;
          	for(i = L->next;i->next!=NULL;i = i->next)
          	{
          		for(j = i;j->next!=NULL;)
          		{
          			if(i->data==j->next->data)
          			{
          				node_dele(L,j);	
          			}
          			else
          			{
          				j = j->next;
          			}
          		}
          	}
          }

      1. 注意事项:删除重复的节点后,不需要移动 j ,继续将i与 j->next比较。

    9. 销毁

      1. int link_destroy(Plink L)
        {
        	if(L==NULL)
        	{
        		printf("销毁失败\n");
        		return -1;
        	}
        	Plink t = L;
        	while(t!=NULL)
        	{
        		t = t->next;
        		free(L);
        		L = t;
        	}
        	printf("销毁成功\n");
        }

    10. 单向链表的优缺点

      1. 优点

        1. 插入删除不需要移动元素,只需要修改指针。

        2. 节点之间不连续,可以充分利用内存碎片存储数据。

        3. 不需要预估存储空间。

        4. 节点个数不受限制。

      2. 不足

        1. 修改查找需要循环遍历节点。

        2. 相同长度的线性表,与顺序表相比单链表占用空间较多。

        3. 只能从头往后访问,不能反向访问。

  2. 双向链表

    • 作用

      • 单向链表只能单向访问链表,而双向链表可以正序或倒序访问查找链表

      • 单向链表不能自我删除,每次都需要找到要删除结点的前一个结点进行删除,引入双向链表可以实现自我删除,找到要删除的结点,让要删除的前驱结点链接到要删除结点的后继结点,然后删除结点即可。

    • 结构体类型格式

        • typedef struct node
          {
              union{
                  int len;
                  int data;    
              };
              struct node *pro;//前一个节点地址
              struct node *next;//后一个节点地址
          }Link,*Plink;

    • 双向链表的相关操作

      • 双向链表的创建
        • 
          Plink creat_double()
          {
          	Plink p = malloc(sizeof(Link));
          	if(p==NULL)
          	{
          		printf("申请失败\n");
          		return NULL;
          	}
          	p->len = 0;
          	p->pro = NULL;
          	p->next = NULL;
          	return p;
          }
          • 功能:创建一个双向链表头结点。

          • 参数:void

          • 返回值:申请到的头结点的地址指针

          • 思路:在堆区申请一个头结点的空间大小,对其进行初始化,数据域len为0,指针域为NULL

          • 注意:判断申请到的空间是否合法

      • 判空
        • int empty(Plink L)
          {
          	if(L==NULL)
          	{
          		return 1;
          	}
          	return 0;
          }
          • 功能:判断双向链表是否为空

          • 返回值:真和假,空 是 1,不空是0,int

          • 参数:双向链表

          • 思路:为空的条件 1、头结点的指针域为空 2、头结点的指针域为0

          • 注意:判断接收到的双向链表是否合法

      • 头插
        • 1、没有1号节点时 新节点p后指针置空 新节点前指针指向头节点 头节点后指针指向新节点
          2、有1号节点时 新节点后指针指向1号节点 新节点前指针指向头节点 1号节点前指针指向新节点 头节点后指针指向新节点。

            • 
              int front_insert(Plink L,int e)
              {
              	if(empty(L))
              	{
              		printf("头插失败\n");
              		return -1;
              	}
              
              	Plink p = malloc(sizeof(Link));
              	p->data = e;
              	if(L->next==NULL)//没有1号节点时
              	{
              		p->next = NULL;
              		p->pro = L;
              		L->next = p;
              	}
              	else//有1号节点时
              	{
              		p->next = L->next;
              		p->pro = L;
              		L->next->pro = p;
              		L->next = p;
              	}
              	L->len++;
              }
              • 功能:在头结点的后面插入一个结点

              • 返回值:成功1 失败0

              • 参数:双向链表、要插入的元素

              • 思路:1、给要插入元素申请结点

              • 2、将要插入的结点插在头结点的后面

              • 3、链表长度+1

              • 注意:判断接收到的双向链表是否合法

      • 尾插法
        • 1、没有1号节点时 新节点p后指针置空 新节点前指针指向头节点 头节点后指针指向新节点
          2、有1号节点时 新节点后指针指向空 新节点前指针指向 t t的后指针指向新节点p

            • int rear_insert(Plink L,int e)
              {
              	if(empty(L))
              	{
              		printf("尾插失败\n");
              		return -1;
              	}
              
              	Plink p = malloc(sizeof(Link));
              	p->data = e;
              	if(L->next==NULL)//没有1号节点时
              	{
              		p->next = NULL;
              		p->pro = L;
              		L->next = p;
              	}
              	else//有1号节点时
              	{
              		int i;
              		Plink t  =L;
              		for(i = 0;i<L->len;i++)//循环len次指向最后一个节点
              		{
              			t = t->next;
              		}
              		p->next = NULL;
              		t->next = p;
              		p->pro = t;
              	}
              	L->len++;	
              }
              • 功能:在头结点的后面插入一个结点

              • 返回值:成功1 失败0

              • 参数:双向链表、要插入的元素

              • 思路:1、给要插入元素申请结点

              • 2、将要插入的结点插在头结点的后面

              • 3、链表长度+1

              • 注意:判断接收到的双向链表是否合法

      • 双向链表的遍历
        • int output_link(Plink L)
          {
          	if(empty(L)||L->len==0)
          	{
          		printf("输出失败\n");
          		return -1;
          	}
          	int i;
          	Plink t = L;
          	for(i = 0;i<L->len;i++)
          	{
          		t = t->next;
          		printf("%d\t",t->data);
          	}
          	printf("\n");
          	return 0;
          }
          
          
          • 功能:共头到尾输出双链表【也可以从尾到头输出双链表】

          • 返回值:无

          • 参数:双链表

          • 思路:只要双链表不空,从头结点开始一个接着一个的输出

      • 任意位置插入
          • 
            int anypos_insert(Plink L,int pos,int e)
            {
            	if(pos<1||pos>L->len+1||empty(L))
            	{
            		printf("插入失败\n");
            		return -1;
            	}
            	int i;
            	Plink t = L;
            	for(i = 0;i<pos-1;i++)//循环pos-1次指向待插入节点的前驱
            	{
            		t  =t->next;
            	}
            	Plink p = malloc(sizeof(Link));
            	p->data = e;
            
            	p->next = t->next;
            	p->pro = t;
            	t->next->pro = p;
            	t->next = p;
            	L->len++;
            	return 0;
            
            }
            • 功能:在双链表长度范围之内的任意位置,插入一个结点

            • 返回值:成功1 失败0 int

            • 参数:双链表、要插入的数据、指定的位置

            • 思路:知道要插入的位置

      • 任意位置删除
          • int anypos_dele(Plink L,int pos)
            {
            	if(pos<1||pos>L->len||L->len==0||empty(L))
            	{
            		printf("删除失败\n");
            		return -1;
            	}
            	int i;
            	Plink Q,t = L;
            	for(i = 0;i<pos-1;i++)
            	{
            		t = t->next;
            	}
            	Q = t->next;//保留要删除的节点
            	t->next = t->next->next;
            	Q->next->pro = t;
            	free(Q);
            	Q=NULL;
            	L->len--;
            }

      • 链表销毁

        • int link_destroy(Plink L)
          {
          	if(L==NULL)
          	{
          		printf("销毁失败\n");
          		return -1;
          	}
          	Plink t = L;
          	while(t!=NULL)
          	{
          		t = t->next;
          		free(L);
          		L = t;
          	}
          	printf("销毁成功\n");
          }

  3. 脑图

二、作业

完成单链表操作,要求节点构造类型。

1、建立学生结构体(学号,姓名,成绩)

2、循环调用头插法创建整表

3、遍历单链表

4、任意位置插入一个完整的学生信息

5、任意位置删除一个学生。

6、单链表逆置

7、单链表按照学生成绩排序。

代码解答:

头文件:
#include "stu.h"

int main(int argc, const char *argv[]) {
    Plink L = creat_link();  // 创建链表头节点
    int pos;  // 用于记录插入或删除操作的位置
    student new_student;  // 用于存储插入的学生信息
    int ch;  // 记录用户的选择

    // 无限循环,直到用户选择退出
    while (1) {
        // 打印功能菜单
        printf("\n----------菜单----------\n");
        printf("\t1、输入学生信息(头插法创建链表)\n");
        printf("\t2、任意位置插入一个学生\n");
        printf("\t3、任意位置删除一个学生\n");
        printf("\t4、遍历单链表\n");
        printf("\t5、单链表逆置\n");
        printf("\t6、单链表按照学生成绩排序\n");
        printf("\t0、退出程序\n");
        printf("\n请输入你的选择:");
        scanf("%d", &ch);  // 获取用户的菜单选择

        // 根据用户输入选择对应功能
        switch (ch) {
            case 1:  // 输入学生信息,头插法创建链表
                input_link(L);  // 调用函数通过头插法创建链表
                break;

            case 2:  // 任意位置插入学生信息
                printf("请输入要插入的位置:");
                scanf("%d", &pos);  // 获取用户指定的位置
                printf("请输入学生的学号、姓名、成绩:\n");
                scanf("%d %s %f", &new_student.id, new_student.name, &new_student.score);  // 输入新学生信息
                anypos_insert(L, pos, new_student);  // 调用插入函数在指定位置插入
                break;

            case 3:  // 任意位置删除学生
                printf("请输入要删除的学生位置:");
                scanf("%d", &pos);  // 获取要删除的学生位置
                anypos_dele(L, pos);  // 调用删除函数删除指定位置的学生
                break;

            case 4:  // 遍历链表
                output_lin(L);  // 调用遍历函数输出链表内容
                break;

            case 5:  // 链表逆置
                link_re(L);  // 调用逆置函数对链表进行逆置
                printf("链表逆置成功!\n");
                break;

            case 6:  // 按照学生成绩排序
                bubble_sort(L);  // 调用排序函数对链表进行冒泡排序(根据成绩)
                printf("链表按成绩排序成功!\n");
                break;

            case 0:  // 退出程序
                printf("程序退出!\n");
                return 0;  // 退出程序

            default:  // 输入无效时提示
                printf("输入无效,请重新选择!\n");
                break;
        }
    }

    return 0;
}
函数文件:
#include "stu.h"

// 创建链表的头节点,返回头节点指针
Plink creat_link() {
    Plink p = malloc(sizeof(llink));  // 分配头节点的内存
    if (NULL == p) {
        printf("申请头节点失败\n");  // 内存分配失败时的错误处理
        return NULL;
    }
    p->len = 0;       // 初始化链表长度为0
    p->next = NULL;   // 初始化链表的next指针为NULL
    return p;         // 返回头节点
}

// 通过头插法输入学生信息并创建链表
int input_link(Plink L) {
    if (NULL == L) {
        printf("单链表不存在,创建失败\n");  // 检查链表是否存在
        return -1;
    }

    int n;
    printf("请输入学生个数:");
    scanf("%d", &n);   // 输入学生个数
	L->len = n;        // 初始化链表长度

    for (int i = 0; i < n; i++) {
        // 分配新节点的内存
        Plink p = (Plink)malloc(sizeof(llink));
        if (p == NULL) {
            printf("内存分配失败\n");  // 内存分配失败时的处理
            return -1;
        }

        // 输入学生信息
        printf("请输入第 %d 个学生的学号、姓名、成绩:\n", i + 1);
        scanf("%d %s %f", &p->data.id, p->data.name, &p->data.score);

        // 头插法插入新节点
        p->next = L->next;  // 新节点的next指向当前链表的第一个节点
        L->next = p;        // 链表头节点的next指向新节点
		L->len += 1;         // 更新链表长度
    }

    return 0;
}

// 遍历链表,输出学生信息
int output_lin(Plink L) {
    if (L == NULL || L->next == NULL) {
        printf("链表为空!\n");  // 如果链表为空则提示
        return -1;
    }

    Plink t = L->next;  // 从第一个有效节点开始遍历
    while (t != NULL) {
        // 输出当前节点的学生信息
        printf("学号:%d\t姓名:%s\t成绩:%.2f\n", t->data.id, t->data.name, t->data.score);
        t = t->next;  // 移动到下一个节点
    }

    return 0;
}

// 在链表中的任意位置插入一个学生信息
int anypos_insert(Plink L, int pos, student new_student) {
    // 检查插入位置是否合法
	if (pos < 1 || pos > L->len + 1) {
		printf("插入失败\n");
		return -1;
	}

    // 分配新节点的内存
	Plink p = (Plink)malloc(sizeof(llink));
	if (NULL == p) {
		printf("内存分配失败\n");
		return -1;
	}
	p->data = new_student;  // 将新学生信息赋给新节点

    // 找到插入位置的前一个节点
	Plink t = L;
	for (int i = 1; i < pos; i++) {
		t = t->next;
	}

    // 插入新节点
	p->next = t->next;  // 新节点的next指向当前节点的next
	t->next = p;        // 当前节点的next指向新节点
	L->len++;           // 更新链表长度
	printf("插入成功\n");
	return 0;
}

// 删除链表中任意位置的学生
int anypos_dele(Plink L, int pos) {
    // 检查链表是否为空或删除位置是否合法
	if (L == NULL || pos < 1 || pos > L->len) {
		printf("删除失败\n");
		return -1;
	}

    // 找到删除位置的前一个节点
	Plink t = L;
	for (int i = 1; i < pos; i++) {
		t = t->next;
	}

    // 删除节点并释放内存
	Plink Q = t->next;       // 指向要删除的节点
	t->next = t->next->next; // 前一个节点的next指向删除节点的下一个节点
	free(Q);                 // 释放删除节点的内存
	Q = NULL;                // 防止野指针
	L->len--;                // 更新链表长度
	return 0;
}

// 逆置链表
int link_re(Plink L) {
    // 如果链表为空或只有一个节点则无需逆置
    if (L == NULL || L->next == NULL) {
        printf("链表为空或只有一个节点,无需逆置\n");
        return -1;
    }

    Plink prev = NULL;   // 前一个节点指针
    Plink curr = L->next;  // 当前节点指针
    Plink next = NULL;   // 下一个节点指针

    // 遍历链表并逆置
    while (curr != NULL) {
        next = curr->next;  // 保存当前节点的下一个节点
        curr->next = prev;  // 当前节点的next指向前一个节点
        prev = curr;        // 更新前一个节点为当前节点
        curr = next;        // 更新当前节点为下一个节点
    }

    L->next = prev;  // 最终头节点的next指向逆置后的第一个节点
    printf("链表逆置成功!\n");
    return 0;
}

// 使用冒泡排序按学生成绩对链表进行排序
int bubble_sort(Plink L) {
    // 如果链表为空或只有一个节点则无需排序
	if (NULL == L || L->next == NULL) {
		return -1;
	}

    Plink p, q;
    student t;  // 临时存储变量用于交换数据

    // 外层循环遍历链表
	for (p = L->next; p != NULL; p = p->next) {
        // 内层循环进行两两比较
		for (q = L->next; q->next != NULL; q = q->next) {
			if (q->data.score > q->next->data.score) {
                // 交换节点数据
				t = q->data;
				q->data = q->next->data;
				q->next->data = t;
			}
		}
	}
	return 0;
}
主函数文件:
#ifndef _STU_H_     // 防止头文件重复包含
#define _STU_H_

#include <myhead.h>  // 包含自定义头文件(假设这个文件包含标准库头文件和其他必要声明)

// 定义学生信息的结构体
typedef struct {
    int id;          // 学生学号
    char name[20];   // 学生姓名,最大长度为20
    float score;     // 学生成绩
} student;

// 定义链表节点结构体,用于存储学生信息
typedef struct iceberg {
    // 使用共用体:链表头节点存储长度,普通节点存储学生信息
    union {
        int len;       // 链表头节点存储链表长度
        student data;  // 普通节点存储学生信息
    };
    struct iceberg *next;  // 指向下一个节点的指针
} llink, *Plink;  // llink为链表节点结构体类型,Plink为指向链表节点的指针类型

// 函数声明

// 创建链表头节点,返回链表头节点指针
Plink creat_link();

// 输入学生信息,通过头插法创建链表
int input_link(Plink);

// 遍历链表,输出学生信息
int output_lin(Plink);

// 在链表的任意位置插入学生信息
int anypos_insert(Plink, int, student);

// 删除链表的任意位置的学生信息
int anypos_dele(Plink, int);

// 逆置链表,反转链表中的节点顺序
int link_re(Plink);

// 使用冒泡排序按学生成绩对链表进行排序
int bubble_sort(Plink);

#endif  // _STU_H_

成果展现:

 

 

 

三、总结

 学习内容概述

1. 链表基本概念:

理解单链表、双向链表和循环链表的结构及其操作方式。

单链表:

每个节点只包含一个指向下一个节点的指针。

双向链表:

每个节点包含指向前一个节点和后一个节点的两个指针。

循环链表:

尾节点指向头节点,形成一个环形结构。

2.链表的基本操作:

包括链表的插入、删除、遍历、修改等操作。

头插法和尾插法:

不同的插入方法影响链表的构建顺序和效率。

节点的删除:

包括删除头节点、中间节点和尾节点的不同处理方式。

3. 链表与顺序表的对比:

链表在动态插入和删除时效率高,而顺序表适合快速随机访问。

4. 复杂链表操作:

包括链表的逆序、合并、排序等高阶操作。

 学习难点

1. 链表的指针操作:

需要时刻保持对指针的准确控制,尤其在插入、删除和逆序操作中容易出现指针丢失或错误指向的情况。

2. 双向链表的节点操作:

每次操作时需要同时维护前驱指针和后继指针,操作复杂度增加。

3. 循环链表的特殊性:

因为尾节点指向头节点,操作时需要额外的边界条件判断,避免无限循环。

4. 链表的逆序与合并:

涉及多个指针的同步操作,特别是当链表长度不一致或需要多次遍历时容易出错。

主要事项

1. 链表的节点插入与删除:

在单链表中进行头插法和尾插法时,注意在头插时更新头节点指针,在尾插时确保尾节点指针指向新节点。

2. 内存管理与泄漏问题:

链表的节点是动态分配的内存,必须确保在删除节点时正确释放内存,以防止内存泄漏。

3. 链表的遍历与输出:

在遍历链表时,特别是在循环链表中,注意终止条件,防止出现死循环。

4. 逆序与排序:

逆序操作需要在遍历的同时调整链表的指针指向,排序操作则需额外的算法支持(如冒泡排序或归并排序)来调整节点位置。

未来学习的重点

1. 复杂链表结构的实现:

学习如何实现双向循环链表,并深入理解其操作方式与使用场景。

2. 链表排序与优化:

研究如何高效地对链表进行排序,尤其是在不占用额外内存的前提下,完成链表的原地排序。

3. 链表在实际项目中的应用:

链表在内存管理、图结构、数据库等领域有广泛应用,未来可以通过实战项目进一步强化对链表操作的掌握。

4. 多种数据结构结合使用:

探索链表与其他数据结构(如栈、队列、树等)结合的应用场景,增强对数据结构整体的理解和应用能力。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2158569.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaWeb - 5 - 前端工程化 Element

一.前后端分离开发 前后端混合开发 缺点&#xff1a;沟通成本高&#xff0c;分工不明确&#xff0c;不便管理&#xff0c;不便维护拓展 前后端分离开发 当前最为主流的开发模式&#xff1a;前后端分离 前后端分离开发中很重要的是API接口文档&#xff08;如&#xff1a;YApi&…

AH2212-12V转4.2V充电芯片

AH2212——12V转4.2V充电芯片&#xff0c;峰值2A输出编程电流&#xff0c;实现精准同步开关降压锂电池充电 随着科技的不断发展&#xff0c;移动电源、智能穿戴、电动工具等设备的应用越来越广泛&#xff0c;对电池充电芯片的需求也日益增大。本文将为您介绍一款高性能的充电芯…

通过iFIX在ARMxy边缘计算网关上实现维护管理

在当今快速发展的工业环境中&#xff0c;维护管理的有效性直接影响到生产效率和设备可靠性。随着物联网和边缘计算的兴起&#xff0c;传统的维护方式正在被更智能和高效的解决方案所替代。ARMxy系列的BL340控制器&#xff0c;凭借其灵活的IO配置和强大的处理能力&#xff0c;成…

linux使用docker安装运行kibana报错“Kibana server is not ready yet“的解决办法

首先docker log <container-id>查看日志是什么问题(以下是我的最后一条日志报错): {"type":"log","timestamp":"2024-09-23T12:27:0700:00","tags":["error","elasticsearch-service"],"pi…

【中关村在线-注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

基于单片机的无线宠物自动喂食系统设计

本设计研究了一种无线宠物自动喂食器&#xff0c;其功能是先将宠物饲料放入其中&#xff0c;通过设定喂食时间点&#xff0c;当到达这一时间点后&#xff0c;系统开始播报语音同时控制步进电机转动&#xff0c;自动进行喂食。本设计主要研究怎么设定时间并进行投喂&#xff0c;…

(学习记录)使用 STM32CubeMX——GPIO引脚输出配置

学习总结&#xff1a;&#xff08;学习总结&#xff09;STM32CubeMX HAL库 学习笔记撰写心得https://blog.csdn.net/Wang2869902214/article/details/142435481 STM32F103C8T6的GPIO引脚输出配置 时钟配置 &#xff08;学习记录&#xff09;使用 STM32CubeMX——配置时钟&…

【软件工程】可行性研究

一、目的 二、任务 三、步骤 四、结果&#xff1a;可行性研究报告 例题 选择题

创新学生宿舍管理:Spring Boot框架实践

第2章 开发环境与技术 学生宿舍管理系统的编码实现需要搭建一定的环境和使用相应的技术&#xff0c;接下来的内容就是对学生宿舍管理系统用到的技术和工具进行介绍。 2.1 MYSQL数据库 本课题所开发的应用程序在数据操作方面是不可预知的&#xff0c;是经常变动的&#xff0c;没…

pdf怎么删除空白页?分享5个删除pdf页面的方法(批量删除法)

pdf文件因其跨平台、格式稳定的特性&#xff0c;已成为我们工作、学习中不可或缺的一部分。那么在编辑pdf格式文档中&#xff0c;总会遇到一些难题&#xff0c;比如说pdf怎么删除空白页 pdf与word一样&#xff0c;具备了多种编辑功能&#xff0c;只不过是word倾向于编辑&#x…

zabbix入门单机部署

zabbix官网 1进入官网后选择右上角Download 选择你要的版本以及需要的组件&#xff0c;网页下方会自动生成需要操作的步骤 &#xff0c;跟着步骤一步一步安装即可&#xff1a; 这里跟着官网步骤一步步走下去就可以了 但是需要注意的是安装 yum install centos-release-scl源…

活动报名| 探索存内计算的未来,共话AGI时代

活动日期&#xff1a;2024年09月28日 下午一点到6点 地点&#xff1a;杭州技术转移中心 三楼路演厅 议程亮点&#xff1a; 存内计算技术架构以及最新趋势AGI开源项目交流存内计算实操上板体验 存内计算 ——突破物理极限的下一代算力技术 直接消除“存”“算”界限&…

【C++】10道经典面试题带你玩转二叉树

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C ⚙️操作环境:Leetcode/牛客网 目录 一.根据二叉树创建字符串 二.二叉树的层序遍历 三.二叉树的层序遍历 II 四.二叉树的最近公共祖先 五.二叉搜索树与双向链表 六.从前序与中序遍历序列构造二叉树 七.从中序与后序遍历…

【笔记】机器学习算法在异常网络流量监测中的应用

先从一些相对简单的综述类看起&#xff0c;顺便学学怎么写摘要相关工作的&#xff0c;边译边学 机器学习算法在异常网络流量监测中的应用 原文&#xff1a;Detecting Network Anomalies in NetFlow Traffic with Machine Learning Algorithms Authors: Quc Vo, Philippe Ea, Os…

【雅特力AT32】I2C 配置工具Artery_I2C_Timing_Configuration的使用

功能 可以实现对主机和从机的时钟、数字滤波、模拟滤波配置。 环境安装 软件环境 Artery_I2C_Timing_Configuration.exe &#xff08;附件压缩包含安装包和配置工具使用指南&#xff0c;需要免费自取&#xff09; /*** function name:* - void i2c_init(i2c_type *i2c_x…

马尔科夫蒙特卡洛_吉布斯抽样算法(Markov Chain Monte Carlo(MCMC)_Gibbs Sampling)

定义 输入:目标概率分布的密度函数 p ( x ) p(x) p(x),函数 f ( x ) f(x) f(x) 输出: p ( x ) p(x) p(x)的随机样本 x m 1 , x m 2 , ⋯ , x n x_{m1},x_{m2},\cdots,x_n xm1​,xm2​,⋯,xn​,函数样本均值 f m n f_{mn} fmn​; 参数:收敛步数 m m m,迭代步数 n n n。 (1)初…

【Linux】常用指令(下)(内含more、less、 head、tail、date、find、grep、zip、tar以及学习笔记)

文章目录 前言1. more指令2. less指令&#xff08;重要&#xff09;3. head指令4. tail指令5. 管道&#xff08;做到学会使用即可&#xff09;6. date指令6.1 时间戳 7. cal指令8. find指令9. grep指令10. zip/unzip指令11. tar指令 前言 Linux下的常用指令终于要在本文落下帷…

如给Excel表格设置保护,防止表格被移动或删除

在日常工作和学习中&#xff0c;Excel表格是我们经常使用的工具之一。然而&#xff0c;在某些情况下&#xff0c;我们可能需要保护Excel工作簿的结构&#xff0c;防止工作表被随意移动或删除&#xff0c;以确保数据的完整性和安全性。下面小编就来给大家详细介绍如何在Excel中设…

J Transl Med结肠癌分子分型+简单实验

目录 技术路线 实验设计&#xff08;药物敏感性&#xff09; 亮点 方法 从 TCGA 和 GEO 数据库下载大量和单细胞 RNA 测序以及 CRC 的临床数据。HRGs 和 LMRGs 来自分子特征数据库。使用 R 软件包 DESeq2 进行差异表达分析。使用无监督聚类进行分子亚型。使用单变量 Cox 回…

Hbase日常运维

1 Hbase日常运维 1.1 监控Hbase运行状况 1.1.1 操作系统 1.1.1.1 IO 群集网络IO&#xff0c;磁盘IO&#xff0c;HDFS IO IO越大说明文件读写操作越多。当IO突然增加时&#xff0c;有可能&#xff1a;1.compact队列较大&#xff0c;集群正在进行大量压缩操作。 2.正在执行…