数据结构-线性表顺序单项链表双向链表循环链表

news2024/11/19 13:42:13

1数据结构概述

数据结构是计算机组织、存储数据的方式。是思想层面的东西,和具体的计算机编程语言没有关系。可以用任何计算机编程语言去实现这些思想。

1.1 数据逻辑结构

反映数据逻辑之间的逻辑关系,这些逻辑关系和他们咱在计算机中的存储位置无关。

常用的逻辑结构有:

线性结构:数据元素存在一对一的互相关系;

树形结构:数据元素存在一对多的互相关系;

图形结构:数据元素存在多对多的互相关系。

1.2数据存储结构(物理结构)

数据元素在计算机存储空间中的 存放形式称为数据存储结构,或者物理结构。

一般来说,一种数据的逻辑结构开业有多种存储结构,常见的存储结构:顺序存储和链式存储。

2.线性表

2.1基本概念

线性表是由零个或多个数据元素组成的有序序列。

特征:

数据元素之间是有顺序的;

数据元素个数是由限的;

一般情况下,在强类型语言中,数据元素的类型是相同的。

2.2数学定义

线性表是n个元素组成的有限序列,a1,a2,a3....an,其中ai(1<=i<=n)是表项,n是线性表的长度,

其中,a1为线性表的第一个元素,只有后继元素,没有前驱元素,an为线性表的最后一个元素,只有前驱元素,没有后继元素。除了a1和an之外的其他元素,既有前驱元素,,也有后继元素。

2.3线性表的顺序存储结构

线性表的顺序存储结构,指的是用一段连续的存储空间来存储线性表中的数据元素。

//dynamicArray.h

#pragma once //防止头文件被重复包含

class DynamicArray
{
private:
	int* data;//线性表的数据元素的存储的空间
	int size;//线性表的大小
	int capacity;//线性表的容量
public:
	DynamicArray();
	DynamicArray(int capacity);
	~DynamicArray();

	//添加元素
	void pushBack(int value);//尾部添加
	void insertByIndex(int index, int value);//在表中指定位置前面插入元素位置

	//查询相关操作
	int getCapacity();//返回动态数组的容量
	int getSize();//返回动态数组的大小
	int getValueByIndex(int index);//返回指定位置的元素
	int front();//返回动态数组的第一个元素
	int back();//返回动态数组的最后一个元素

	//删除元素
	void popBack();//删除尾部
	void delByIndex(int index);//删除指定位置的元素
	

	//打印动态数组
	void printDynamicArray();
};

//dynamicArray.c

#include "dynamicArray.h"
#include <iostream>
using  namespace std;

DynamicArray::DynamicArray()
{
	capacity = 5;
	data = new int[capacity];
	size = 0;
}
DynamicArray::DynamicArray(int capacity)
{
	this->capacity = capacity;
	data = new int[capacity];
	size = 0;
}
DynamicArray::~DynamicArray()
{
	if (data != nullptr)
	{
		delete[] data;
		data = nullptr;
	}
}
void DynamicArray::pushBack(int value)
{
	if (capacity == size)
	{
		//容量已满,需要扩容,容量扩充一倍
		int* temp_data = new int[capacity * 2];
		//复制原来空间中的数据到新的空间
		for (int i = 0; i < size; i++)
		{
			temp_data[i] = data[i];
		}
		delete[]data;
		data = temp_data;
		capacity = capacity * 2;
	}
	data[size] = value;
	size++;
}
void DynamicArray::insertByIndex(int index,int value)
{
	if (index<0 || index>size - 1)
	{
		return;
	}
	if (capacity == size)
	{
		//容量已满,需要扩容,容量扩充一倍
		int* temp_data = new int[capacity * 2];
		for (int i = 0; i < size; i++)
		{
			temp_data[i] = data[i];
		}
		delete[]data;
		data = temp_data;
		capacity *= 2;
	}
	//新元素插在索引index的前面,所以从index开始的元素都要后移
	for (int i = size-1; i >=index; i--)
	{
			data[i + 1] = data[i];
	}
	data[index] = value;

	size++;
}
void DynamicArray::printDynamicArray()
{
	for (int i = 0; i < size; i++)
	{
		cout << data[i] << " ";
	}
	cout << endl;
}
int  DynamicArray::getCapacity()
{
	return capacity;
}
int DynamicArray::getSize()
{
	return size;
}
int  DynamicArray::getValueByIndex(int index)
{
	if (index<0 || index>size - 1)
	{
		return NULL;
	}
	return data[index];
}
int DynamicArray::front()
{
	if(size>0)
	{
		return data[0];
	}
	return NULL;
}
int DynamicArray::back()
{
	if (size > 0)
	{
		return data[size - 1];
	}
	return NULL;
}
void DynamicArray::popBack()
{
	if (size > 0)
	{
		size--;
	}
	
}
void DynamicArray::delByIndex(int index)
{
	if (index < 0 || index>size - 1)
	{
		return;
	}
	for (int i = index; i < size-1; i++)
	{
		data[i]=data[i+1];
	}

	size--;
}

void test_dynamicarry()
{
	DynamicArray* da = new DynamicArray();
	da->pushBack(11);
	da->pushBack(12);
	da->pushBack(13);
	da->pushBack(14);
	da->pushBack(15);

	da->printDynamicArray();
	da->insertByIndex(2,88);
	da->printDynamicArray();
	da->popBack();
	da->printDynamicArray();
	da->delByIndex(2);
	da->printDynamicArray();
	cout << "此动态数组的容量为:" << da->getCapacity() << endl;
	cout << "此动态数组的大小为:" << da->getSize() << endl;
	cout << "此动态数组的第三个元素为:" << da->getValueByIndex(2) << endl;
	cout << "此动态数组中第一个元素为:" << da->front() << endl;
	cout << "此动态数组中最后一个元素为:" << da->back() << endl;
	
	delete da;
}
//设计一个线性表的顺序存储结构,给线性表中插入8个整数,删除其中的奇数。
void test_homework()
{
	DynamicArray* hk = new DynamicArray();
	hk->pushBack(1);
	hk->pushBack(2);
	hk->pushBack(3);
	hk->pushBack(4);
	hk->pushBack(5);
	hk->pushBack(6);
	hk->pushBack(8);
	hk->pushBack(8);
	hk->getSize();
	hk->printDynamicArray();
	int len = hk->getSize();
	for (int i = 0; i < len ;)
	{
		if(hk->getValueByIndex(i) % 2 == 1)
		{
			hk->delByIndex(i);
			
		}
    else
        {
            i++;
        }
	}
	hk->printDynamicArray();
}

2.4线性表之单向链式存储结构

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) +指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

结点结构:

┌───┬───┐

│data │next │

└───┴───┘

data域--存放结点值的数据域

next域--存放结点的直接后继的地址(位置)的指针域(链域)

链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)。

头指针head和终端结点

单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。

终端结点无后继,故终端结点的指针域为空,即NULL。

链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

一个单向链表的节点被分成两个部分。第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。单向链表只可向一个方向遍历。

练习:

设计以恶搞链式线性表,给此线性表插入十个整数,删除其中的最大值(假设最大值唯一)

// LinkList.h

#pragma once
//节点类
class LinkNode
{
public:
	int data;//数据域,存放数据元素
	LinkNode* next;//指向下一个节点的指针

public:
	LinkNode();
	LinkNode(int value);
};

//链表本身的类
class LinkList
{
private:
	LinkNode* head;//头指针,指向头节点
	int size;//链表大小

public:
	LinkList();
	~LinkList();

	//添加元素
	void pushBack(int value);//尾部添加
	void insertByIndex(int index, int value);//指定位置添加

	//查找操作
	int getSize();//返回链表的长度
	int findByIndex(int index);//返回指定位置的元素
	int findIndexByValue(int value);//返回指定元素所在的位置,如果有相同元素,只返回第一个
	int front();//返回第一个元素
	int back();//返回最后一个元素

	//删除元素
	void popBack();//尾部删除
	void delByIndex(int index);//删除指定位置元素

	//打印链表
	void printLinkList();
};


//LinkList.c

#include <iostream>
#include "linkList.h"

using namespace std;


LinkNode::LinkNode()
{
	data = NULL;
	next = nullptr;
}

LinkNode::LinkNode(int value)
{
	data = value;
	next = nullptr;
}

LinkList::LinkList()
{
	head = new LinkNode;
	size = 0;
}

LinkList::~LinkList()
{
	LinkNode* curr = head;
	LinkNode* temp = nullptr;

	while (curr != nullptr)
	{
		temp = curr;
		curr = curr->next;
		delete temp;
	}
}

void LinkList::pushBack(int value)
{
	//新建节点
	LinkNode* newNode = new LinkNode(value);
	//找到最后一个节点
	LinkNode* temp = head;
	while (temp->next != nullptr)
	{
		temp = temp->next;
	}
	//修改相应指针
	temp->next = newNode;

	size++;
}
void LinkList::insertByIndex(int index, int value)
{
	if (index < 0 || index > size - 1)
	{
		return;
	}
	//新建节点
	LinkNode* newNode = new LinkNode(value);
	
	LinkNode* curr = head;
	//找到index节点前面的节点
	for (int i = 0; i < index; i++)
	{
		curr = curr->next;
	}
	//修改相应指针
	newNode->next = curr->next;
	curr->next = newNode;

	size++;
}
int LinkList::getSize()
{
	if (size > 0)
	{
		return size;
	}
}
//返回指定位置元素
int LinkList::findByIndex(int index)
{
	if (index < 0 || index > size - 1)
	{
		return NULL;
	}
	LinkNode* curr = head;
	for (int i = 0; i <= index ; i++)
	{
		curr = curr->next;
	}
	return curr->data;

}

int LinkList::findIndexByValue( int value)
{
	int index = -1;
	LinkNode* temp = head->next;
	while (temp != nullptr)
	{
		index++;
		if (temp->data == value)
		{
			return index;
		}
		temp = temp->next;
	}
	return -1;
}

int LinkList::front()
{
	if (head->next != nullptr)
	{
		return head->next->data;
	}
	return NULL;
}
int LinkList::back()
{
	if (head->next == nullptr)
	{
		return NULL;
	}
	//找到最后一个节点
	LinkNode* temp = head;
	while (temp->next != nullptr)
	{
		temp = temp->next;
	}
	return temp->data;
}

//删除
void  LinkList::popBack()
{
	if (head->next == nullptr)
	{
		return;
	}
	LinkNode* curr = head;
	LinkNode* prev = nullptr;

	while (curr->next != nullptr)
	{
		prev = curr;
		curr = curr->next;
	}
	prev->next = nullptr;
	delete curr;

	size--;
}
void LinkList::delByIndex(int index)
{
	if (index < 0 || index > size - 1)
	{
		return;
	}
	LinkNode* curr = head;
	for (int i = 0; i < index; i++)
	{
		curr = curr->next;
	}
	LinkNode* prev = curr->next;
	curr->next = prev->next;
	delete prev;

	size--;
}


void LinkList::printLinkList()
{
	//找到最后一个节点
	LinkNode* temp = head;
	while (temp->next != nullptr)
	{
		temp = temp->next;
		cout << temp->data << " ";
	}
	cout << endl;
}

void test_linklist()
{
	LinkList list1;
	for (int i = 0; i < 5; i++)
	{
		list1.pushBack(i + 11);
	}
	list1.printLinkList();
	list1.insertByIndex(2, 88);
	list1.printLinkList();
	
	cout << "此链表的第六个元素为:" << list1.findByIndex(5) << endl;
	cout << "此链表的长度为:" << list1.getSize() << endl;

	list1.delByIndex(2);
	list1.printLinkList();


}
void test_homework()
{
	LinkList list2;
	list2.pushBack(5);
	list2.pushBack(6);
	list2.pushBack(7);
	list2.pushBack(9);
	list2.pushBack(10);
	list2.pushBack(15);
	list2.pushBack(18);
	list2.pushBack(20);
	list2.printLinkList();
	int max = list2.front();
	for (int i = 0; i < list2.getSize(); i++)
	{
		if (list2.findByIndex(i) > max)
		{
			max = list2.findByIndex(i);
		}
	}
	cout << list2.getSize() << endl;
	cout << max << endl;
	int maxindex = list2.findIndexByValue(max);
	list2.delByIndex(maxindex);
	list2.printLinkList();

	
}

2.5 线性链表之双向链表

单向链表的节点中只有一个指向其后继的指针,使得单项链表只能从节点依次往后遍历。要访问某个节点的前驱,很不方便。为了克服单项链表的这个缺点,引入了双向链表。双向链表节点中有两个指针,分别指向前驱和后继,所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

双向链表的插入

练习:

设计一个双向链表,向其中插入几个元素,然后逆序该链表。

思路:创建一个新链表,旧链表从头删除,新链表从头添加。

要求写一个函数,实现此功能

#pragma once
//节点类
class DoubleLinkNode
{
public:
	int data;
	DoubleLinkNode* prev;
	DoubleLinkNode* next;

public:
	DoubleLinkNode();
	DoubleLinkNode(int value);
};

//链表本身的类
class DoubleLinkList
{
private:
	DoubleLinkNode* head;
	int size;

public:
	DoubleLinkList();
	~DoubleLinkList();

	//添加元素
	void pushBack(int value);//尾插
	void pushFront(int value);//头插


	//打印双向链表
	void printDoubleLinkList();

	//查询相关操作
	int getSize();//返回双向链表的长度
	int front();//返回双向链表的第一个元素
	int back();//返回双向链表的最后一个元素

	//删除元素
	void popBack();//尾部删除
	void popFront();//头部删除
};

//c
#include <iostream>
#include"doubleLinkList.h"
using namespace std;

DoubleLinkNode::DoubleLinkNode()
{
	data = NULL;
	prev = nullptr;
	next = nullptr;
}

DoubleLinkNode::DoubleLinkNode(int value)
{
	data = value;
	prev = next = nullptr;
}

DoubleLinkList::DoubleLinkList()
{
	head = new DoubleLinkNode();
	size = 0;
}

DoubleLinkList::~DoubleLinkList()
{
	DoubleLinkNode* curr = head;
	DoubleLinkNode* temp = nullptr;

	while (curr != nullptr)
	{
		temp = curr;
		curr = curr->next;
		delete temp;
	}
}

void DoubleLinkList::pushBack(int value)
{
	//新建节点
	DoubleLinkNode* newNode = new DoubleLinkNode(value);
	//找到最后一个节点
	DoubleLinkNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
	}
	//修改相关指针
	curr->next = newNode;
	newNode->prev = curr;

	size++;
}

void DoubleLinkList::pushFront(int value)
{
	DoubleLinkNode* newNode = new DoubleLinkNode(value);
	if (size > 0)//或者使用 if (head->next != nullptr)
	{
		newNode->next = head->next;
		head->next = newNode;
		newNode->prev = head;
		newNode->next->prev = newNode;
	}
	else
	{
		head->next = newNode;
		newNode->prev = head;
	}

	size++;
}


void DoubleLinkList::printDoubleLinkList()
{
	DoubleLinkNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
		cout << curr->data << " ";
	}
	cout << endl;
}

int DoubleLinkList::getSize()
{
	return size;
}

int DoubleLinkList::front()
{
	if (head->next != nullptr)
	{
		return head->next->data;
	}
	return NULL;
}

int DoubleLinkList::back()
{
	DoubleLinkNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
	}
	return curr->data;
}

void DoubleLinkList::popBack()
{
	if (head->next == nullptr)
	{
		return;
	}
	DoubleLinkNode* curr = head;
	while (curr->next != nullptr)
	{
		curr = curr->next;
	}
	curr->prev->next = nullptr;
	delete curr;

	size--;
}

void DoubleLinkList::popFront()
{
	if (head->next == nullptr)
	{
		cout << "没有元素" << endl;
		return;
	}

	DoubleLinkNode* curr = head->next;
	if (curr->next != nullptr)
	{
		curr->next->prev = head;
	}
	head->next = curr->next;
	delete curr;

	size--;
}




void test_doublelinklist()
{
	DoubleLinkList* dl = new DoubleLinkList();
	for (int i = 0; i < 5; i++)
	{
		dl->pushBack(i + 20);
	}
	dl->printDoubleLinkList();
	dl->pushFront(88);
	dl->printDoubleLinkList();

	cout << "此双向链表的大小为:" << dl->getSize() << endl;
	cout << "此双向链表的第一个元素为:" << dl->front() << endl;
	cout << "此双向链表的最后一个元素为:" << dl->back() << endl;
	dl->popBack();
	dl->printDoubleLinkList();
	dl->popFront();
	dl->printDoubleLinkList();

	delete dl;
}

DoubleLinkList* reverseDoubleLinkList(DoubleLinkList* list)
{
	DoubleLinkList* list2 = new DoubleLinkList;
	while (list->getSize() != 0)
	{
		list2->pushFront(list->front());
		list->popFront();
	}
	return list2;
}

void reverseDoubleLinkList2(DoubleLinkList*& list)
{
	DoubleLinkList* list2 = new DoubleLinkList;
	cout << "list: " << &list << endl;
	cout << "list2: " << &list2 << endl;

	while (list->getSize() != 0)
	{
		list2->pushFront(list->front());
		list->popFront();
	}
	list = list2;
	cout << "list: " << &list << endl;
	/*while (list2->getSize() != 0)
	{
		list->pushBack(list2->front());
		list2->popFront();
	}
	delete list2;*/
}

void test_reverse()
{
	DoubleLinkList* list1 = new DoubleLinkList();
	for (int i = 0; i < 8; i++)
	{
		list1->pushBack(i + 11);
	}
	list1->printDoubleLinkList();

	DoubleLinkList* list2 = reverseDoubleLinkList(list1);
	list2->printDoubleLinkList();

	delete list1;
	delete list2;
}

void test_reverse_2()
{
	DoubleLinkList* list1 = new DoubleLinkList();
	for (int i = 0; i < 8; i++)
	{
		list1->pushBack(i + 11);
	}
	list1->printDoubleLinkList();
	cout << "list1: " << &list1 << endl;

	reverseDoubleLinkList2(list1);
	cout << "list1: " << &list1 << endl;
	list1->printDoubleLinkList();
}

2.6线性表之循环链表

循环列表是一种线性表的数据结构,其中最后一个节点的指针指向头节点,形成一个环状结构。

定义与特点

定义‌:

循环列表(Circular List)是一种特殊的线性表,其最后一个节点的指针不是指向NULL,而是指向头节点,形成一个闭环。‌

特点:

无界性‌:从任一节点出发,可以遍历到所有节点,无需判断边界。

循环性‌:操作(如遍历)时,可以无缝地从尾节点回到头节点。

应用广泛‌:常用于实现循环队列、约瑟夫环等问题。

练习:解决约瑟夫环问题

约瑟夫问题:有n个人围城一个圈,首先第一个人从1开始报数,报到第m个人,令其出列,然后再从下一个人开始再从1开始报数,报道第m个人,令其出列。如此下去,直到所有人全部出列。

打印出列顺序。

#pragma once

class CirlceLinkNode
{
public:
	int data;
	CirlceLinkNode* next;
	

public:
	CirlceLinkNode();
	CirlceLinkNode(int value);
};

class CircleLinkList
{
public:
	CirlceLinkNode* head;
	int size;

public:
	CircleLinkList();
	~CircleLinkList();

	void pushBack(int value);
	void pushFront(int value);

	int getSize();
	int front();
	int back();

	void popBack();
	void popFront();

	void printCircleLinkList();

	void yuesefu(int value);
    void yuesefu();//约瑟夫环

};

#include <iostream>
#include "circleLinkList.h"

using namespace std;

CirlceLinkNode::CirlceLinkNode()
{
	data = NULL;
	next = nullptr;
}

CirlceLinkNode::CirlceLinkNode(int value)
{
	data = value;
	next = nullptr;
}

CircleLinkList::CircleLinkList()
{
	head = new CirlceLinkNode;
	head ->next = head;
	size = 0;
}

CircleLinkList::~CircleLinkList()
{
	CirlceLinkNode* curr =  head->next;
	CirlceLinkNode* temp;
	while (curr != head)
	{
		temp = curr;
		curr = curr->next;
		delete temp;
	}
	delete head;
}

void CircleLinkList::pushBack(int value)
{
	CirlceLinkNode* newNode = new CirlceLinkNode(value);
	CirlceLinkNode* curr = head;
	while (curr->next != head)
	{
		curr = curr->next;
	}
	curr->next = newNode;
	newNode->next = head;

	size++;
}
void CircleLinkList::pushFront(int value)
{
	CirlceLinkNode* newNode = new CirlceLinkNode(value);
	newNode->next = head->next;
	head->next = newNode;

	size++;
}

int CircleLinkList::getSize()
{
	return size;
}

int CircleLinkList::front()
{
	if (size > 0)
	{
		return head->next->data;
	}
	return NULL;
}

int CircleLinkList::back()
{
	if (size > 0)
	{
		CirlceLinkNode* curr = head;
		while (curr->next != head)
		{
			curr = curr->next;
		}
		return curr->data;
	}
	return NULL;
}

void CircleLinkList::popBack()
{
	if (head->next == head)
	{
		return;
	}
	CirlceLinkNode* curr = head;
	CirlceLinkNode* prev = nullptr;
	while (curr->next != head)
	{
		prev = head;
		curr = curr->next;
	}
	prev->next = head;
	delete curr;
	
	size--;
}

void CircleLinkList::popFront()
{
	if (head->next == head)
	{
		return;
	}
	CirlceLinkNode* curr = head->next;
	head->next = curr->next;
	delete curr;

	size--;
}

void CircleLinkList::printCircleLinkList()
{
	CirlceLinkNode* curr = head;
	while (curr->next != head)
	{
		curr = curr->next;
		cout << curr->data << " ";
	}
	cout << endl;
}


void test_circle()
{
	CircleLinkList cl;
	for (int i = 0; i < 8; i++)
	{
		cl.pushBack(i + 30);
	}
	cl.printCircleLinkList();
	cl.pushFront(88);
	cl.printCircleLinkList();
	cout << "此循环链表额长度为: " << cl.getSize() << endl;
	cout << "此循环链第一个元素为: " << cl.front() << endl;
	cout << "此循环链最后一个元素为: " << cl.back() << endl;
	cl.popFront();
	cl.printCircleLinkList();
}

void CircleLinkList::yuesefu()
{
	CirlceLinkNode* curr = head;
	CirlceLinkNode* prev = nullptr;
	/*int size = 8;
	while (size > 0)
	{
		for (int i = 0; i < value; i++)
		{
			prev = curr;
			if (curr->next == head)
			{
				curr = curr->next;
			}
			curr = curr->next;
		}
		prev->next = curr->next;
		cout << curr->data << " ";
		size--;
	}*/
	while (size > 0)
	{
		for (int i = 1; i <= 3; i++)
		{
			prev = curr;
			curr = curr->next;
			if (curr == head)
			{
				curr = curr->next;
				prev = head;
			}
		}
		prev->next = curr->next;
		cout << curr->data << " ";

		delete curr;
		curr = prev;
		size--;
	}
}

void test_yuesefu()
{
	CircleLinkList* yuecl = new CircleLinkList;
	for (int i = 1; i < 9; i++)
	{
		yuecl->pushBack(i);
	}
	yuecl->printCircleLinkList();
	//yuecl->yuesefu(3);
	yuecl->yuesefu();
}

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

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

相关文章

专题三_二分查找算法_算法详细总结

目录 二分查找 1.⼆分查找&#xff08;easy&#xff09; 1&#xff09;朴素二分查找&#xff0c;就是设mid(leftright)/2,xnums[mid],t就是我们要找的值 2&#xff09;二分查找就是要求保证数组有序的前提下才能进行。 3&#xff09;细节问题&#xff1a; 总结&#xff1a…

P3565 [POI2014] HOT-Hotels

~~~~~ P3565 [POI2014] HOT-Hotels ~~~~~ 总题单链接 ~~~~~ 2024.9.10&#xff1a;DP方程有问题&#xff0c;已修改&#xff0c;同时更新了长链剖分优化版本。 思路 ~~~~~ 设 g [ u ] [ i ] g[u][i] g[u][i] 表示在 u u u 的子树内&#xff0c;距离 u u u 为 i i i 的点的…

了解国产光耦合器的核心功能和应用

光耦合器或光隔离器是现代电子产品中的关键组件&#xff0c;它能够在没有电接触的情况下在系统的不同部分之间安全地传输信号。这是通过基于光的信号传输来实现的&#xff0c;它可以隔离电路&#xff0c;防止高压损坏敏感元件。近年来&#xff0c;国产光耦合器取得了重大进展&a…

孙怡带你深度学习(1)--神经网络

文章目录 深度学习神经网络1. 感知器2. 多层感知器偏置 3. 神经网络的构造4. 模型训练损失函数 总结 深度学习 深度学习(DL, Deep Learning)是机器学习(ML, Machine Learning)领域中一个新的研究方向。 从上方的内容包含结果&#xff0c;我们可以知道&#xff0c;在学习深度学…

OpenHarmony鸿蒙开发( Beta5.0)智能油烟机开发实践

样例简介 本Demo是基于Hi3516开发板&#xff0c;使用开源OpenHarmony开发的应用。本应用主要功能有&#xff1a; 可以搜索本地指定目录的图片和视频文件&#xff0c;并可进行点击播放。 可以通过wifi接收来自手机的美食图片以及菜谱视频&#xff0c;让我们对美食可以边学边做…

昨晚,OpenAI震撼发布o1大模型!我们正式迈入了下一个时代。

大半夜的&#xff0c;OpenAI抽象了整整快半年的新模型。 在没有任何预告下&#xff0c;正式登场。 正式版名称不叫草莓&#xff0c;草莓只是内部的一个代号。他们的正式名字&#xff0c;叫&#xff1a; 为什么取名叫o1&#xff0c;OpenAI是这么说的&#xff1a; For complex …

TCP核心机制

TCP基本特点&#xff1a;有连接&#xff0c;面向字节流&#xff0c;全双工&#xff0c;可靠传输(TCP最核心的机制) 核心机制一(确认应答): 在网络中&#xff0c;可能我们传输的消息会因为诸多原因导致发送到对方手中的顺序不一样&#xff0c;举个例子&#xff1a; 在这张图中…

【鸿蒙开发从0到1 支付宝界面布局实现day11】

鸿蒙开发案例-支付宝界面 一.布局思路二.页面搭建1.整体stack布局底部的tab2.主体区域的架子:头部主体界面(层叠关系,主题页面可以滚动)3.给主体内容填内容(1).完成快捷导航(2)服务导航 4.装饰图片 三.整体效果展示1.效果展示2.完整代码演示 四.总结 一.布局思路 整体stack布局…

成型的程序

加一个提示信息 加上python 常用的包 整个程序打包完 250M 安装 960MB matplot numpy pandas scapy pysearial 常用的包 (pyvisa)… … 啥都有 Python 解释器组件构建 要比 lua 容易的多 &#xff08;C/Rust 的组件库)

Vue3 父组件向子组件传值:异步数据处理的显示问题

一、问题场景 假设我们有一个父组件和一个子组件&#xff0c;父组件需要经过一些复杂的计算或者异步操作才能得到要传递给子组件的值。在数据还没有准备好的时候&#xff0c;子组件尝试获取并显示这个值&#xff0c;这就可能导致子组件没有数据可显示或者显示了一个不正确的初…

简单有趣的python小程序(涵源代码)

目录 tkinter 计算器 2.计算题练习 猜数字 烦人的程序 无法拒绝的请假条。。。 爬虫 你想看豆瓣评分前十的电影? WXpython 记事本&#xff08;可保存&#xff09;​编辑 数字逻辑 解方程 tkinter 计算器 import tkinter as tk import tkinter.messagebox as mroot…

使用ChatGPT撰写论文,一定要掌握加强理论深度的八个策略!

大家好,感谢关注。我是七哥,一个在高校里不务正业,折腾学术科研AI实操的学术人。关于使用ChatGPT等AI学术科研的相关问题可以和作者多多交流,相互成就,共同进步,为大家带来最酷最有效的智能AI学术科研写作攻略。 在学术论文的写作中,加强论文的理论深度是非常重要的一个…

nacos明明配置了远程连接地址却一直连接本地的详细配置解释

大家时间都很珍贵&#xff0c;我直接把方法放这 这个是yml文件&#xff0c;我们配置yml文件的时候&#xff0c;一定要把他的服务发现地址写了 这里是针对bootstrap做出的文件&#xff0c;注意名字&#xff0c;要和我们在yml文件里面的spring名字一样 yml discovery:是发现的意…

C到C++入门基础知识

一&#xff1a;命名空间&#xff1a;namespace &#xff08;一&#xff09;&#xff1a;命名空间的定义 注&#xff1a;命名空间只能定义在全局&#xff0c;不能定义在函数内部。 &#xff08;1&#xff09;类似于C语言的结构体&#xff0c;C语言的命名空间定义为&#xff1…

Java Enterprise System 体系结构

本章概述了 Java Enterprise System 部署所基于的体系结构概念。 章中描述了一个框架,在此框架内从三维角度对 Java Enterprise System部署体系结构进行了分析,它们分别是:逻辑层、基础结构服务级别和服务质量。这三维在下图中以图解形式显示为正交坐标轴,它们有助于在体系…

Word使用手册

修改样式 编辑word文档时&#xff0c;标题和正文文本通常有不同的格式&#xff0c;如果能将这些格式保存为样式&#xff0c;下一次就能直接调用样式&#xff0c;而不需要重复手动设置格式。 可以将样式通常保存为不同的 样式模板.docx&#xff0c;要调用不同样式集&#xff0…

看Threejs好玩示例,学习创新与技术

我把在一些好玩的ThreeJS的效果&#xff0c;认真分析技术&#xff0c;写成博客&#xff0c;欢迎大家去看。 后面慢慢补充。 看Threejs好玩示例&#xff0c;学习创新与技术(一)https://mp.weixin.qq.com/s/eJeGmnla0D4zEMl4AwFsVw

波克城市 x NebulaGraph|高效数据血缘系统在游戏领域的构建实战

关于波克城市和作者‍‍ 波克城市&#xff0c;一家专注于研发精品休闲游戏的全球化公司&#xff0c;连续七年入选中国互联网综合实力百强&#xff0c;2023 年位列 17 位。波克城市旗下拥有《捕鱼达人》《猫咪公寓2》等精品休闲游戏&#xff0c;全球注册用户超 5 亿&#xff0c;…

AB 1756-L62 与 AB 5069 通过串口通信

PLC AB L62 控制器 插槽2 Path, RS232=2, 3 PLC Compactlogix 5069-SERIAL 配置

【提示词】浅谈GPT等大模型中的Prompt

Prompt是人工智能&#xff08;AI&#xff09;提示词&#xff0c;是一种利用自然语言来指导或激发人工智能模型完成特定任务的方法。在AI语境中&#xff0c;Prompt是一种自然语言输入&#xff0c;通常指的是向模型提出的一个请求或问题&#xff0c;这个请求或问题的形式和内容会…