【数据结构】(C语言):二叉搜索树(不使用递归)

二叉搜索树:

  • 非线性的,树是层级结构。
  • 基本单位是节点,每个节点最多2个子节点。
  • 有序。每个节点,其左子节点都比它小,其右子节点都比它大。
  • 每个子树都是一个二叉搜索树。每个节点及其所有子节点形成子树。
  • 可以是空树。

C语言实现:(使用链表实现,不使用递归)

 创建结构体数据类型(记录二叉搜索树的根节点和数据个数):

typedef struct Link
{
    LinkNode *root;            // 根节点
    int length;                // 统计有多少数据
} LinkBST;                     // 别名

创建二叉搜索树,并初始化:

LinkBST bst;
bst.root = NULL;    // 根节点,初始化为NULL
bst.length = 0;     // 数据个数,初始化为0


创建节点(结构体数据类型),并创建具体节点实例的函数:

// 节点(结构体数据类型)
typedef struct Node
{
    int value;                // 数据类型为整型
    struct Node *left;        // 左子节点
    struct Node *right;       // 右子节点
} LinkNode;                   // 别名
// 函数:创建节点
LinkNode *createNode(int data)
{
    LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));    // 分配节点内存空间
    if(node == NULL)
    {
        perror("Memory allocation failed");
        exit(-1);
    }
    node->value = data;    // 数据
    node->left = NULL;     // 左子节点,初始化为NULL
    node->right = NULL;    // 右子节点,初始化为NULL
    return node;
}


添加元素:

从根节点开始,比对数值。若比它小,往左子树比对;若比它大,往右子树比对;直到找到为空,则为新元素的位置。

void add(LinkBST *bst, int data)	// add a element to the tree
{
	LinkNode *newNode = createNode(data);
	// 若是空树,根节点就是新节点
	if(bst->root == NULL)
	{
		bst->root = newNode;
		bst->length++;
		return ;
	}
	// 非空树,比根节点数值小,往左边比对,比根节点数值大,往右边比对
	LinkNode *cur = bst->root;
	while(1)
	{
		if(data == cur->value) return ;
		if(data < cur->value)
		{
			if(cur->left == NULL)
			{
				cur->left = newNode;
				bst->length++;
				return ;
			}
			cur = cur->left;
		}
		else if(data > cur->value)
		{
			if(cur->right == NULL)
			{
				cur->right = newNode;
				bst->length++;
				return ;
			}
			cur = cur->right;
		}
	}
}

删除元素:

  • 若删除的节点为叶子节点(即无子节点),则直接删除。
  • 若删除的节点只有左子节点,则左子节点替代删除节点。
  • 若删除的节点只有右子节点,则右子节点替代删除节点。
  • 若删除的节点既有左子节点又有右子节点,则找到直接前驱(即删除节点的左子树中的最大值,即删除节点的左子节点的最右节点),直接前驱的值替代删除节点的值,删除直接前驱节点。
void delete(LinkBST *bst,int data)	// delete a element from the tree
{
	// 函数:删除节点的具体操作
	LinkNode *del(LinkNode *node)
	{
		// 只有右子节点,右子节点替代删除节点
		if(node->left == NULL)
		{
			bst->length--;
			return node->right;
		}
		// 只有左子节点,左子节点替代删除节点
		if(node->right == NULL)
		{
			bst->length--;
			return node->left;
		}
		// 左右子节点都有,直接前驱(左子节点的最右节点,即左子树中最大值)替代删除节点,删除直接前驱
		if(node->left && node->right)
		{
			LinkNode *tmp = node, *cur = node->left;
			while(cur->right)
			{
				tmp = cur;
				cur = cur->right;
			}
			node->value = cur->value;
			bst->length--;
			if(tmp != node) tmp->right = cur->left;
			else tmp->left = cur->left;
			return node;
		}
	}
	
	// 函数:找到删除节点
	void delNode(int data)
	{
		LinkNode *parent, *cur = bst->root;
		while(1)
		{
			if(cur == NULL) return ;
			if(data == cur->value)
			{
				// 删除节点若是根节点,根节点接收删除后的节点
				if(cur == bst->root) bst->root = del(cur);
				// 删除节点若是左子节点,父节点的左子节点接收删除后的节点
				else if(data < parent->value) parent->left = del(cur);
				// 删除节点若是右子节点,父节点的右子节点接收删除后的节点
				else if(data > parent->value) parent->right = del(cur);
				return ;
			}
			if(data < cur->value)
			{
				parent = cur;
				cur = cur->left;
			}
			else if(data > cur->value)
			{
				parent = cur;
				cur = cur->right;
			}
		}
	}
    // 空树,直接退出程序
	if(bst->root == NULL) return ;
	delNode(data);
}

遍历元素:

前序遍历:(顺序:根节点、左子节点、右子节点)

使用数组实现栈(后进先出),数量:一个栈。

1、起始栈中元素为根节点。2、栈中元素依次出栈(并打印),找到元素的右节点和左节点依次入栈(注意:先右后左)。3、重复2,直到栈为空。

void pretraverse(LinkBST *bst)	// show element one by one,(root,left,right)
{
	LinkNode *cur = NULL;
	// 指针数组(数组元素是指针),实现栈(后进先出)
	LinkNode *arr[bst->length];
	int n = 1;
	arr[n-1] = bst->root;
	printf("pretravel: ");
	while(n != 0)
	{
		cur = arr[n-1];
		printf("%d  ", cur->value);
		n--;
		if(cur->right)
		{
			arr[n] = cur->right;
			n++;
		}
		if(cur->left)
		{
			arr[n] = cur->left;
			n++;
		}
	}
	printf("\n");
}

中序遍历:(顺序:左子节点、根节点、右子节点)

使用数组实现栈(后进先出),数量:一个栈。

1、从根节点开始遍历,根节点入栈。2、找左节点依次入栈,找到最左节点后,栈中元素依次出栈(并打印),找右节点入栈。3、重复2,直到节点不存在或者栈为空。

void midtraverse(LinkBST *bst)	// show element one by one,(left,root,right)
{
	printf("midtravel: ");
	LinkNode *cur = bst->root;
	// 指针数组(数组元素是指针),实现栈(后进先出)
	LinkNode *arr[bst->length];
	int n = 0;
	while(cur || n != 0)
	{
		if(cur)
		{
			arr[n] = cur;
			n++;
			cur = cur->left;
		}
		else
		{
			cur = arr[n-1];
			printf("%d  ", cur->value);
			n--;
			cur = cur->right;
		}
	}
	printf("\n");
}

后序遍历:(顺序:左子节点、右子节点、根节点)

使用数组实现栈(后进先出),数量:两个栈(辅助栈,目标栈)。

1、辅助栈中起始元素为根节点。2、辅助栈中元素依次出栈(并入栈目标栈),找到元素的左节点和右节点依次入栈辅助栈(注意:先左后右)。3、重复2,直到辅助栈为空。4、遍历目标栈,并打印。

void posttraverse(LinkBST *bst)	// show element one by one,(left,right,root)
{
	LinkNode *cur = NULL;
	// 指针数组(数组元素是指针),实现栈(后进先出)
	LinkNode *arr[bst->length];    // 辅助栈
	LinkNode *brr[bst->length];    // 目标栈
	int n = 1, m = 0;
	arr[n-1] = bst->root;
	while(n != 0)
	{	
		cur = brr[m] = arr[n-1];    // 辅助栈出栈,目标栈入栈
		n--;
		m++;
		if(cur->left)
		{
			arr[n] = cur->left;    // 辅助栈入栈
			n++;
		}
		if(cur->right)
		{
			arr[n] = cur->right;    // 辅助栈入栈
			n++;
		}
	}
    // 遍历目标栈
	printf("posttravel: ");
	for(int i = m - 1; i >= 0; i--)
	{
		printf("%d  ", brr[i]->value);
	}
	printf("\n");
}

广度遍历(层级遍历):

使用链表实现队列(先进先出),数量:一个队列。

1、队列中起始元素为根节点。2、队列中元素依次从队头出队(并打印),找到元素的左节点和右节点依次从队尾入队(注意:先左后右)。3、重复2,直到队列为空。

void breadthtraverse(LinkBST *bst)	// show element one by one,(levels)
{
	printf("threadtravel: ");
	// 链表:实现队列(先进先出),注:链表的函数在bstqueue.c(完整代码中展示)
	Queue queue;
	queue.header = createQnode(bst->root);    // 头指针,指向第一个元素
	queue.tail = NULL;                        // 尾指针,指向最后一个元素
	LinkNode *cur = NULL;
	while(queue.header)
	{
		cur = queue.header->bstnode;
		printf("%d  ", cur->value);
		popQnode(&queue);                    // 从队头出队(函数在bstqueue.c)
		if(cur->left)
		{
			addQnode(&queue, cur->left);    // 从队尾入队(函数在bstqueue.c)
		}
		if(cur->right)
		{
			addQnode(&queue, cur->right);    // 从队尾入队(函数在bstqueue.c)
		}
	}
	printf("\n");
}

查找元素:

从根节点开始,比对数值。若比它小,往左子树查找;若比它大,往右子树查找;直到找到该元素,则返回1(true),若没有,则返回0(false)。

int find(LinkNode *node, int data)	// if find data,return 1(true),or return 0(false)
{
	LinkNode *cur = node;
	while(cur)
	{
		if(data == cur->value) return 1;
		if(data < cur->value) cur = cur->left;
		else if(data > cur->value) cur = cur->right;
	}
	return 0;
}

完整代码:(bstree.c,bstqueue.c(链表实现的队列,用于广度遍历))

// bstree.c
#include <stdio.h>
#include <stdlib.h>
#include "bstqueue.c"    // 引入链表实现的队列,用于广度遍历

/* structure */
typedef struct Node		// node of the binary search tree(bst)
{
	int value;		    // data type is integer
	struct Node *left;	// left child node
	struct Node *right;	// right child node
} LinkNode;

typedef struct Link		//bst(Linkedlist)
{
	LinkNode *root;		// root node
	int length;		    // the number of the tree
} LinkBST;

/* function prototype */
void add(LinkBST *, int);	    // add a element
void delete(LinkBST *,int);	    // delete a element
void pretraverse(LinkBST *);	// show element one by one,(root,left,right)
void midtraverse(LinkBST *);	// show element one by one,(left,root,right)
void posttraverse(LinkBST *);	// show element one by one,(left,right,root)
void breadthtraverse(LinkBST *);	// show element one by one,(levels)
int find(LinkNode *, int);	    // if find data,return 1(true),or return 0(false)

/* main function */
int main(void)
{
	// create binary search tree and initialization
	LinkBST bst;
	bst.root = NULL;
	bst.length = 0;
	printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);

	add(&bst, 15);
	add(&bst, 8);
	add(&bst, 23);
	add(&bst, 19);
	add(&bst, 10);
	add(&bst, 6);
	add(&bst, 9);
	add(&bst, 12);
	
	printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);
	pretraverse(&bst);
	midtraverse(&bst);
	posttraverse(&bst);
	breadthtraverse(&bst);

	printf("find 10(1:true, 0:false): %d\n", find(bst.root, 10));
	printf("find 11(1:true, 0:false): %d\n", find(bst.root, 11));

	delete(&bst, 23);
	delete(&bst, 15);
	delete(&bst, 6);
		
	printf("isempty(1:true, 0:false): %d, length is %d\n", bst.root==NULL, bst.length);
	pretraverse(&bst);
	midtraverse(&bst);
	posttraverse(&bst);
	breadthtraverse(&bst);
	return 0;
}

/* subfunction */
LinkNode *createNode(int data)		// create a node of the binary search tree
{
	LinkNode *node = (LinkNode *)malloc(sizeof(LinkNode));
	if(node == NULL)
	{
		perror("Memory allocation failed");
		exit(-1);
	}
	node->value = data;
	node->left = NULL;
	node->right = NULL;
	return node;
}

void add(LinkBST *bst, int data)	// add a element to the tree
{
	LinkNode *newNode = createNode(data);
	// if empty, root is newNode
	if(bst->root == NULL)
	{
		bst->root = newNode;
		bst->length++;
		return ;
	}
	// if not empty, smaller,to left, biger,to right
	LinkNode *cur = bst->root;
	while(1)
	{
		if(data == cur->value) return ;
		if(data < cur->value)
		{
			if(cur->left == NULL)
			{
				cur->left = newNode;
				bst->length++;
				return ;
			}
			cur = cur->left;
		}
		else if(data > cur->value)
		{
			if(cur->right == NULL)
			{
				cur->right = newNode;
				bst->length++;
				return ;
			}
			cur = cur->right;
		}
	}
}

void delete(LinkBST *bst,int data)	// delete a element from the tree
{
	// subfunction: delete the node
	LinkNode *del(LinkNode *node)
	{
		// if only right child, return right child node
		if(node->left == NULL)
		{
			bst->length--;
			return node->right;
		}
		// if only left child, return left child node
		if(node->right == NULL)
		{
			bst->length--;
			return node->left;
		}
		// both left and right, the max on the left replace the delete node and delete it
		if(node->left && node->right)
		{
			LinkNode *tmp = node, *cur = node->left;
			while(cur->right)
			{
				tmp = cur;
				cur = cur->right;
			}
			node->value = cur->value;
			bst->length--;
			if(tmp != node) tmp->right = cur->left;
			else tmp->left = cur->left;
			return node;
		}
	}
	
	// subfunction: find the delete node
	void delNode(int data)
	{
		LinkNode *parent, *cur = bst->root;
		while(1)
		{
			if(cur == NULL) return ;
			if(data == cur->value)
			{
				// delete node is root,root receive the node after delete
				if(cur == bst->root) bst->root = del(cur);
				// delete node is left,left child of parent receive the node after delete
				else if(data < parent->value) parent->left = del(cur);
				//delete node is right,right child of parent receive the node after delete
				else if(data > parent->value) parent->right = del(cur);
				return ;
			}
			if(data < cur->value)
			{
				parent = cur;
				cur = cur->left;
			}
			else if(data > cur->value)
			{
				parent = cur;
				cur = cur->right;
			}
		}
	}

	if(bst->root == NULL) return ;
	delNode(data);
}

void pretraverse(LinkBST *bst)	// show element one by one,(root,left,right)
{
	LinkNode *cur = NULL;
	// pointer array(stack:LIFO): array, each element is a pointer(point to node)
	LinkNode *arr[bst->length];
	int n = 1;
	arr[n-1] = bst->root;
	printf("pretravel: ");
	while(n != 0)
	{
		cur = arr[n-1];
		printf("%d  ", cur->value);
		n--;
		if(cur->right)
		{
			arr[n] = cur->right;
			n++;
		}
		if(cur->left)
		{
			arr[n] = cur->left;
			n++;
		}
	}
	printf("\n");
}

void midtraverse(LinkBST *bst)	// show element one by one,(left,root,right)
{
	printf("midtravel: ");
	LinkNode *cur = bst->root;
	// pointer array(stack:LIFO): array, each element is a pointer(point to node)
	LinkNode *arr[bst->length];
	int n = 0;
	while(cur || n != 0)
	{
		if(cur)
		{
			arr[n] = cur;
			n++;
			cur = cur->left;
		}
		else
		{
			cur = arr[n-1];
			printf("%d  ", cur->value);
			n--;
			cur = cur->right;
		}
	}
	printf("\n");
}

void posttraverse(LinkBST *bst)	// show element one by one,(left,right,root)
{
	LinkNode *cur = NULL;
	// pointer array(stack:LIFO): array, each element is a pointer(point to node)
	LinkNode *arr[bst->length];
	LinkNode *brr[bst->length];
	int n = 1, m = 0;
	arr[n-1] = bst->root;
	while(n != 0)
	{	
		cur = brr[m] = arr[n-1];
		n--;
		m++;
		if(cur->left)
		{
			arr[n] = cur->left;
			n++;
		}
		if(cur->right)
		{
			arr[n] = cur->right;
			n++;
		}
	}
	printf("posttravel: ");
	for(int i = m - 1; i >= 0; i--)
	{
		printf("%d  ", brr[i]->value);
	}
	printf("\n");
}

void breadthtraverse(LinkBST *bst)	// show element one by one,(levels)
{
	printf("threadtravel: ");
	// queue(FIFO): use Linkedlist implement
	Queue queue;
	queue.header = createQnode(bst->root);
	queue.tail = NULL;
	LinkNode *cur = NULL;
	while(queue.header)
	{
		cur = queue.header->bstnode;
		printf("%d  ", cur->value);
		popQnode(&queue);
		if(cur->left)
		{
			addQnode(&queue, cur->left);
		}
		if(cur->right)
		{
			addQnode(&queue, cur->right);
		}
	}
	printf("\n");
}

int find(LinkNode *node, int data)	// if find data,return 1(true),or return 0(false)
{
	LinkNode *cur = node;
	while(cur)
	{
		if(data == cur->value) return 1;
		if(data < cur->value) cur = cur->left;
		else if(data > cur->value) cur = cur->right;
	}
	return 0;
}
// bstqueue.c
#include <stdlib.h>

/* structure */
typedef struct queueNode	// node of the queue
{
	void *bstnode;			// data type is bst node
	struct queueNode *next;	// point to next node
} Qnode;

typedef struct queue		// queue(Linkedlist)
{
	Qnode *header;		    // point to the top node
	Qnode *tail;		    // point to the last node
} Queue;

/* subfunction */
Qnode *createQnode(void *bstnode)	// create a node of the queue
{
	Qnode *node = (Qnode *)malloc(sizeof(Qnode));
	if(node == NULL)
	{
		perror("Memory allocation failed");
		exit(-1);
	}
	node->bstnode = bstnode;
	node->next = NULL;
	return node;
}

void addQnode(Queue *queue, void *node)	// add a element to the end of the queue
{
	Qnode *qnode = createQnode(node);
	if(queue->tail == NULL) queue->tail = queue->header = qnode;
	else
	{
		queue->tail->next = qnode;
		queue->tail = qnode;
	}
}

void popQnode(Queue *queue)		// delete a element from the top of the queue
{
	queue->header = queue->header->next;
	if(queue->header == NULL) queue->tail = NULL;
}

编译链接: gcc -o bstree bstree.c

执行可执行文件: ./bstree

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Report Design Analysis报告之logic level详解

目录 一、前言 二、Logic Level distribution 2.1 logic level配置 2.2 Logic Level Distribution报告 2.3 Logic Level 报告详情查看 2.4 Route Distributions 报告详情查看 2.5 示例代码 一、前言 ​在工程设计中&#xff0c;如果需要了解路径的逻辑级数&#xff0c;可…

赚钱小思路,送给没有背景的辛辛苦苦努力的我们!

我是一个没有背景的普通人&#xff0c;主要靠勤奋和一股钻劲&#xff0c;这十几年来我的日常作息铁打不变&#xff0c;除了睡觉&#xff0c;不是在搞钱&#xff0c;就是在琢磨怎么搞钱。 ​ 可以说打拼了十几年&#xff0c;各种小生意都做过&#xff0c;以前一直是很乐观的&…

绘唐3最新版本哪里下载

绘唐3最新版本哪里下载 绘唐最新版本下载地址 推文视频创作设计是一种通过视频和文字的形式来进行推广的方式&#xff0c;可以通过一些专业的工具来进行制作。 以下是一些常用的小说推文视频创作设计工具&#xff1a; 视频剪辑软件&#xff1a;如Adobe Premiere Pro、Fina…

人工智能系列-Pandas基础

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” Pandas简介 Pandas是Python语言的拓展程序库&#xff0c;用于数据分析。 Pandas是一个开放源码&#xff0c;BSD许可的库&#xff0c;提供高性能&#xff0c;易于使用的数据结…

SSM养老院管理系统-计算机毕业设计源码02221

摘要 本篇论文旨在设计和实现一个基于SSM的养老院管理系统&#xff0c;旨在提供高效、便捷的养老院管理服务。该系统将包括老人档案信息管理、护工人员管理、房间信息管理、费用管理等功能模块&#xff0c;以满足养老院管理者和居民的不同需求。 通过引入SSM框架&#x…

ChatGPT对话:Scratch编程中一个单词,如balloon,每个字母行为一致,如何优化编程

【编者按】balloon 7个字母具有相同的行为&#xff0c;根据ChatGPT提供的方法&#xff0c;优化了代码&#xff0c;方便代码维护与复用。初学者可以使用7个字母精灵&#xff0c;复制代码到不同精灵&#xff0c;也能完成这个功能&#xff0c;但不是优化方法&#xff0c;也没有提高…

微信小程序毕业设计-医院挂号预约系统项目开发实战(附源码+论文)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;微信小程序毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计…

高考志愿填报,选专业是看兴趣还是看就业?

对于结束高考的学生来说&#xff0c;选择专业的确是一个非常让人头疼的事情。因为很多人都不知道&#xff0c;选专业的时候究竟是应该看一下个人兴趣&#xff0c;还是看未来的就业方向&#xff0c;这也是让不少人都相当纠结的问题。这里分析一下关于专业选择的问题&#xff0c;…

动手学深度学习(Pytorch版)代码实践 -循环神经网络-54循环神经网络概述

54循环神经网络概述 1.潜变量自回归模型 使用潜变量h_t总结过去信息 2.循环神经网络概述 ​ 循环神经网络&#xff08;recurrent neural network&#xff0c;简称RNN&#xff09;源自于1982年由Saratha Sathasivam 提出的霍普菲尔德网络。循环神经网络&#xff0c;是指在全…

字符串——string类的常用接口

一、string类对象的常见构造 二、string类对象的容量操作 三、string类对象的访问及遍历操作 四、string类对象的修改操作 一、string类对象的常见构造 1.string() ——构造空的string类对象&#xff0c;也就是空字符串 2.string(const char* s) ——用字符串来初始化stri…

【微服务】springboot对接Prometheus指标监控使用详解

目录 一、前言 二、微服务监控概述 2.1 微服务常用监控指标 2.2 微服务常用指标监控工具 2.3 微服务使用Prometheus监控优势 三、环境准备 3.1 部署Prometheus服务 3.2 部署Grafana 服务 3.3 提前搭建springboot工程 3.3.1 引入基础依赖 3.3.2 配置Actuator 端点 3.…

代码随想录算法训练营第14天|226.翻转二叉树、101. 对称二叉树、104. 二叉树的最大深度、111.二叉树的最小深度

打卡Day14 1.226.翻转二叉树2.101. 对称二叉树扩展100. 相同的树572. 另一棵树的子树 3.104. 二叉树的最大深度扩展559.n叉树的最大深度 3.111.二叉树的最小深度 1.226.翻转二叉树 题目链接&#xff1a;226.翻转二叉树 文档讲解&#xff1a; 代码随想录 &#xff08;1&#x…

博客的部署方法论

有了域名后&#xff0c;可以方便其他人记住并访问&#xff0c;历史上不乏大企业花大价钱购买域名的&#xff1a; 京东域名换成 JD.com&#xff0c;并且说是为了防止百度吸引流量&#xff0c;为什么&#xff1f;唯品会买下域名 VIP.COM 或花费千万 ‍ 域名提供商 如果想要域…

Xilinx FPGA:vivado关于真双端口的串口传输数据的实验

一、实验内容 用一个真双端RAM&#xff0c;端口A和端口B同时向RAM里写入数据0-99&#xff0c;A端口读出单数并存入单端口RAM1中&#xff0c;B端口读出双数并存入但端口RAM2中&#xff0c;当检测到按键1到来时将RAM1中的单数读出显示到PC端&#xff0c;当检测到按键2到来时&…

普通Java工程如何在代码中引用docker-compose.yml中的environment值

文章目录 一、概述二、常规做法1. 数据库配置分离2. 代码引用配置3. 编写启动类4. 支持打包成可执行包5. 支持可执行包打包成docker镜像6. docker运行 三、存在问题分析四、改进措施1. 包含environment 变量的编排文件2. 修改读取配置文件方式3. 为什么可以这样做 五、运行效果…

股票Level-2行情是什么,应该怎么使用,从哪里获取数据

行情接入方法 level2行情websocket接入方法-CSDN博客 相比传统的股票行情&#xff0c;Level-2行情为投资者打开了更广阔的视野&#xff0c;不仅限于买一卖一的表面数据&#xff0c;而是深入到市场的核心&#xff0c;提供了十档乃至千档的行情信息&#xff08;沪市十档&#…

JavaWeb-【1】HTML

笔记系列持续更新,真正做到详细!!本次系列重点讲解后端,那么第一阶段先讲解前端 目录 1、Javaweb技术体系 2、BS架构说明 3、官方文档 4、网页组成 5、HTML 6、HTML快速入门 7、HTML基本结构 8、HTML标签 ​9、HTML标签使用细节 ①、font标签 ②、字符实体 ③、标…

图神经网络dgl和torch-geometric安装

文章目录 搭建环境dgl的安装torch-geometric安装 在跑论文代码过程中&#xff0c;许多小伙伴们可能会遇到一些和我一样的问题&#xff0c;就是文章所需要的一些库的版本比较老&#xff0c;而新版的环境跑代码会报错&#xff0c;这就需要我们手动的下载whl格式的文件来安装相应的…

SSM中小学生信息管理系统 -计算机毕业设计源码02677

摘要 随着社会的发展和教育的进步&#xff0c;中小学生信息管理系统成为学校管理的重要工具。本论文旨在基于SSM框架&#xff0c;采用Java编程语言和MySQL数据库&#xff0c;设计和开发一套高效、可靠的中小学生信息管理系统。中小学生信息管理系统以学生为中心&#xff0c;通过…

机器学习筑基篇,​Ubuntu 24.04 编译安装 Python 及多版本切换

[ 知识是人生的灯塔&#xff0c;只有不断学习&#xff0c;才能照亮前行的道路 ] Ubuntu 24.04 编译安装最新Python及多版本切换 描述&#xff1a;说到机器学习&#xff0c;人工智能&#xff0c;深度学习不免会提到Python这一门编程语言&#xff08;人生苦短&#xff0c;及时Pyt…