数据结构(常见的排序算法)

news2025/1/16 8:06:41

1.插入排序

1.1直接插入排序

在[0  end]区间上有序,然后将(end+1)的数据与前面有序的数据进行比较,将(end+1)的数据插入,这样[0  end+1]区间上就是有序的,然后再向后进行比较。

例如:想要数据调整为升,数组(end+1)位置的数据,前面是比它小的数据,后面是比它大的数据。

时间复杂度:O(N^2) 

动图显示:

实现代码:

//插入排序(升序)
void intsertsort(int* arr, int num );

 

参数:指向数组首元素的指针,数组中的元素个数

//插入排序(升序)
void intsertsort(int* arr, int num )
{
	for (int i = 0;i<num-1;i++)
	{
		//只考虑一次排序,在[0,end]上是有序的
		int end = i;
		int tmp = arr[end + 1];
		while (end >= 0)
		{
			if (tmp < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}
		}
		arr[end + 1] = tmp;
	}
		

}

1.2希尔排序

希尔排序是从直接插入排序演化而来的,分为两步,一个步是预处理,另一步是直接插入排序。

预处理:预处理是将原来的数据处理的尽可能有序,让数据尽可能的在最终排序完成的位置附近,这样就可以避免直接插入排序 数组(end+1)位置的数直接与[0  end]这个区间的数全部比较。

时间复杂度:O(N*logN) 

动图演示:

实现代码:

//希尔排序

void shellsort(int* arr, int num);

函数参数:指向数组首元素的指针,数组中的元素个数

//希尔排序(升序)
#include<stdio.h>
//*希尔排序
//*1.预排序
//*2.插入排序
//*时间复杂度O(N^1.3)
//*

void shellsort(int* arr, int num)
{
	int gap = num;
	while (gap > 1)
	{
		//保证最后一次是1,gap不是1时实现预排序,是1时实现插入排序
		gap = gap / 3 + 1;
		for (int i = 0; i < num - gap; i++)
		{
			int end = i;
			int tmp = arr[end + gap];
			while (end >= 0)
			{
				if (tmp < arr[end])
				{
					arr[end + gap] = arr[end];
					end=end-gap;
				}
				else
				{
					break;
				}
			}
			arr[end + gap] = tmp;

			
		}
		
	}
	


}

注:在gap不等于1的时候,是在执行预处理,当gap等于1的时候实在实现直接插入排序。

2.选择排序

2.1选择排序

选择排序,就是一趟选择出一个数组中的一个最大值或者最小值

时间复杂度:O(N^2)

动图演示: 

实现代码:

//选择排序
void selectsort(int* arr, int num)

函数参数:指向数组首元素的指针,数组中的元素个数

//交换函数
void swap(int*x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

//选择排序
void selectsort(int* arr, int num)
{
	//提升效率,可以同时进行最大值和最小值的排序
	int begin = 0, end = num ;
	while (begin < end)
	{
		int imin = begin, imax = begin;
		for (int i = begin; i < end; i++)
		{
			if (arr[i] > arr[imax])
			{
				imax = i;
			}

			if (arr[i] < arr[imin])
			{
				imin = i;
			}
		}

		if (begin == imax)
			imax = imin;

		//放置最小值和最大值
		swap(&arr[imin], &arr[begin]);
		swap(&arr[imax], &arr[end - 1]);

		begin++;
		end--;
	}
	

}

注:实现函数中是一趟找出数组中的最大值和最小值,这算是一种优化。

2.2堆排序 

先堆数组进行堆排序,升序建大堆,降序建小堆,下面用小堆举例子,数组的首元素一定是数组的最大数,将首元素与数组的最后一个数进行交换,然后对数组[0  end-1]区间进行向下调整。继续,直到真个数组有序。

时间复杂度:O(N*logN)

动图演示:

注:上面演示的数组一开始已经建大堆。

实现代码:

//向下调整函数
void downjust_big(HPDataType* root, int num,int tmp)

参数:指向数组首元素的指针,数组中的元素个数,需要向下调整的位置

//向下调整创建大堆
void downjust_big_heap(HPDataType* arr, int num)

参数:指向数组首元素的指针,数组中的元素个数

//大堆升序
void downjust_arry_up(HPDataType* arr, int num)

参数:指向数组首元素的指针,数组中的元素个数

//交换函数
void Swap(HPDataType* x, HPDataType* y)

参数:指向需要交换元素的两个指针

//交换函数
void Swap(HPDataType* x, HPDataType* y)
{
	HPDataType tmp = *x;
	*x = *y;
	*y = tmp;
}


//向下调整函数
void downjust_big(HPDataType* root, int num,int tmp)
{
	assert(root);
	int parent = tmp;

	//假设左孩子和右孩子中大的那个是左孩子
	int child = parent * 2 + 1;

	//如果孩子节点不在堆中,就直接结束
	while (child < num)
	{
		//(1)如果右孩子大于左孩子
		//(2)如果没有右孩子,那么左孩子一定是最大的
		if (root[child] < root[child + 1] && (child + 1) < num)
		{
			//将最大的孩子修改为右孩子
			child++;
		}

		if (root[parent] < root[child])
		{
			Swap(&root[parent], &root[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			//直接跳出循环
			break;
		}
	}
}


//向下调整创建大堆
void downjust_big_heap(HPDataType* arr, int num)
{
	assert(arr);
	for (int i = (num - 2) / 2; i >= 0; i--)
	{
		downjust_big(arr, num, i);
	}
}


//大堆升序
void downjust_arry_up(HPDataType* arr, int num)
{
	assert(arr);
	downjust_big_heap(arr, num);
	while (num)
	{
		Swap(&arr[0], &arr[num - 1]);
		num--;
		downjust_big(arr, num, 0);
	}
}

3.交换排序 

3.1冒泡排序 

冒泡排序,实际上就是两两比较,满足条件的两两交换,一趟可以选择出数组中的最大值后者最小值(取决于升序还是降序),直到将数据中的全部数据排序完成。

时间复杂度:N(N^2) 

动图演示: 

实现代码:

//冒泡排序

void BubbleSort(int* arr, int n) ;

函数参数:指向数组首元素的指针,数组中的元素个数

//冒泡排序(升序)
//* 时间复杂度O(N^2)

void swap(int* x, int* y)
{
	int tmp = *x;
	*x = *y;
	*y = tmp;
}

void BubbleSort(int* arr, int n)
{
	
	for (int j = 0; j < n-1; j++)
	{
		int flag = 1;
		//一次遍历
		for (int i = 0; i < n -j- 1; i++)
		{
			if (arr[i] > arr[i + 1])
			{
				swap(&arr[i], &arr[i + 1]);
				flag = -1;
			}
		}
		if (flag == 1)
			break;
	}
	


}

3.2快速排序  

快速排序:就是选择一个数据,将数组中的数分为小于该数和大于该数的两个部分,小于该数的部分在该数的左边,大于的放在该数的右边。然后该数的位置为分界,然后在两个小区间重复上面的操作。 

时间复杂度:O(N*logN) 

代码演示:

hoare法:

 挖坑法:

前后指针法:

初学者适合先看挖坑法进行一个理解。 

实现代码:

//快速排序(hoare)
void QuickSort(int* arr, int left, int right)
 ;

参数:指向数组首元素的指针,指向数组最左边位置,指向数组最右边位置

//快速排序
void QuickSort(int* arr, int left, int right)
{

	if (left >= right)
		return;


	int begin = left, end = right;
	int keyi = begin;


	while (begin < end)
	{
		//左边当钥匙时,是右边开始移动

	//当找到一个比keyi小的数字时,停下来
		while (begin<end && arr[end] >= arr[keyi])
		{
			end--;
		}

		//右边开始移动
		while (begin<end && arr[begin] <=arr[keyi])
		{
			begin++;
		}

		swap(&arr[begin], &arr[end]);
	}
	//begin和end相遇
		swap(&arr[keyi], &arr[end]);
	    keyi = begin;
	

	//接下来就是递归
	//标准值左右两边
		QuickSort(arr, left, keyi - 1);
		QuickSort(arr, keyi+1,right);

}

注:选择最左边的数为标志数,那么那就不许从右边进行开始比较。 

//快速排序(挖坑法)
void QuickSort(int* arr, int left, int right);

参数:指向数组首元素的指针,指向数组最左边位置,指向数组最右边位置

//快速排序(挖坑法)
void QuickSort(int* arr, int left, int right)
{

	if (left >= right)
		return;


	

	int begin = left, end = right;

	int keyi = arr[left];


	while (begin < end)
	{
		//左边当钥匙时,是右边开始移动

	//当找到一个比keyi小的数字时,停下来
		while (begin < end && arr[end] >=keyi)
		{
			end--;
		}
		arr[begin] = arr[end];
		//右边开始移动
		while (begin < end && arr[begin] <= keyi)
		{
			begin++;
		}
		arr[end] = arr[begin];
	}
	//begin和end相遇
	arr[end] = keyi;
	keyi = begin;
	//接下来就是递归
	//标准值左右两边
	QuickSort(arr, left, keyi - 1);
	QuickSort(arr, keyi + 1, right);

}

//快速排序(前后指针法) 

void QuickSort(int* arr, int left, int right)

参数:指向数组首元素的指针,指向数组最左边位置,指向数组最右边位置

void QuickSort(int* arr, int left, int right)
{

	if (left >= right)
		return;


	int prev = left, cur = left + 1;

	int keyi = left;

	while (cur<=right)
	{
		//cur指针找比arr[keyi]小的数值
		if (arr[cur] < arr[keyi] && arr[++prev] != arr[cur])
			swap(&arr[cur], &arr[prev]);

		cur++;
	}
	
	swap(&arr[keyi], &arr[prev]);
	keyi = prev;
	
	//接下来就是递归
	//标准值左右两边
	QuickSort(arr, left, keyi - 1);
	QuickSort(arr, keyi + 1, right);

}

由于快速排序使用递归,如果数据过大,就很容易出现栈的溢出,因此需要改为非递归。

//快速排序(非递归)

实际上,非递归是使用了递归的逻辑,只不过是使用栈数据结构来储存需要进行快速排序的两个区间。

void QuickSortNonR(int* arr, int left, int right) 

参数:指向数组首元素的指针,指向数组最左边位置,指向数组最右边位置

//栈的定义
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;		// 栈顶(指向栈顶元素的下一位)
	int capacity;  // 容量 
}Stack;

// 初始化栈 
void StackInit(Stack* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}

// 入栈 (对应顺序表的尾插)
void StackPush(Stack* ps, STDataType data)
{
	assert(ps);
	//判断插入时的空间
	if (ps->top == ps->capacity)
	{
		//判断栈是否申请空间
		ps->capacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		STDataType* new = (STDataType*)realloc(ps->a, ps->capacity * sizeof(STDataType));
		if (new == NULL)
		{
			perror("StackPush::realloc");
		}
		else
		{
			ps->a = new;
		}
	}

	//尾插
	ps->a[ps->top] = data;
	ps->top++;
}

// 出栈 (对应于顺序表的尾删)
void StackPop(Stack* ps)
{
	assert(ps);
	ps->top--;
}

// 获取栈顶元素 
STDataType StackTop(Stack* ps)
{
	assert(ps);
	return ps->a[ps->top-1];
}

// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0 
int StackEmpty(Stack* ps)
{
	assert(ps);
	//栈为空返回1,栈不为空返回0
	if (ps->top == 0)
	{
		return 0;
	}
	else
	{
		return 1;
	}
}

// 销毁栈 
void StackDestroy(Stack* ps)
{
	assert(ps);
	ps->capacity = ps->top = 0;
	free(ps->a);
	ps->a = NULL;
}

//快速排序(非递归)
void QuickSortNonR(int* arr, int left, int right)
{
	//非递归实际上就是使用栈来模拟递归
	Stack ps;
	StackInit(&ps);

	//将区间数放入栈中
	StackPush(&ps, left);
	StackPush(&ps, right);

	while (StackEmpty(&ps))
	{
		//取出栈的区间
		int end = StackTop(&ps);
		StackPop(&ps);
		int begin = StackTop(&ps);
		StackPop(&ps);
		//去除区间只有一个数值,和区间没有数值
		if (begin < end)
		{
			int keyi = begin;
			int prev = begin;
			int cur = begin + 1;
			while (cur <= end)
			{
				if (arr[cur] < arr[keyi] && arr[++prev] != arr[cur])
					swap(&arr[cur], &arr[prev]);
				cur++;
			}
			swap(&arr[keyi], &arr[prev]);
			keyi = prev;

			//添加小区间,先添加右区间,在添加左区间
			StackPush(&ps, keyi + 1);
			StackPush(&ps, end);
			StackPush(&ps, begin);
			StackPush(&ps, keyi - 1);
		}
	}

	//销毁栈
	StackDestroy(&ps);

}
 3.2.1快速排序优化(三数取中)

如果我们只是单一的选择数组的首元素作为比较的标志数,那么我们就很容易取到过于大或者过于小的数,那么我们的时间复杂度就很容易偏向于O(N^2) ,所以使用三数取中,其取数组的首元素,尾元素和中间元素,在这个三个数中取中间的数,然后将中间的数与数组首位置的数据交换,然后进行一个快速排序。

代码实现:

//三数取中
int ThreeNumMiddle(int* arr, int left, int right) 

参数:指向数组首元素的指针,指向数组最左边位置,指向数组最右边位置

//三数取中
int ThreeNumMiddle(int* arr, int left, int right)
{
	int middle = (right + left) / 2;
	if (arr[left] > arr[right])
	{
		if (arr[right] > arr[middle])
			return right;
		else
		{
			if (arr[left] > arr[middle])
				return middle;
			else
				return left;
		}

	}
	else
	{
		if (arr[middle] > arr[right])
			return right;
		else
		{
			if (arr[left] > arr[middle])
				return left;
			else
				return middle;
		}
	}
}

3.2.2快速排序优化(小区间优化) 

快速排序是一个前序遍历,这个排序的区间的划分上很像二叉树,最终小区间的数量会非常多,其实当区间足够小的时候,不同排序之间的时间差异不是很大,当区间差小于一个数时,使用直接插入排序,这样会很节约很多分区间的时间花费。 

//小区间优化  

//三数取中
int ThreeNumMiddle(int* arr, int left, int right)
{
	int middle = (right + left) / 2;
	if (arr[left] > arr[right])
	{
		if (arr[right] > arr[middle])
			return right;
		else
		{
			if (arr[left] > arr[middle])
				return middle;
			else
				return left;
		}

	}
	else
	{
		if (arr[middle] > arr[right])
			return right;
		else
		{
			if (arr[left] > arr[middle])
				return left;
			else
				return middle;
		}
	}
}


//插入排序(升序)
void intsertsort(int* arr, int num)
{
	for (int i = 0; i < num - 1; i++)
	{
		//只考虑一次排序,在[0,end]上是有序的
		int end = i;
		int tmp = arr[end + 1];
		while (end >= 0)
		{
			if (tmp < arr[end])
			{
				arr[end + 1] = arr[end];
				end--;
			}
			else
			{
				break;
			}
		}
		arr[end + 1] = tmp;
	}


}




void QuickSort(int* arr, int left, int right)
{

	if (left >= right)
		return;

	//小区间优化
	//在小区间中使用快速排序
	if ((right - left) <= 5)
	{
		intsertsort(arr + left, right - left + 1);
		return;
	}


    //三数取中
	int middle = ThreeNumMiddle(arr, left, right);
	swap(&arr[left], &arr[middle]);

	int prev = left, cur = left + 1;

	int keyi = left;

	while (cur<=right)
	{
		//cur指针找比arr[keyi]小的数值
		if (arr[cur] < arr[keyi] && arr[++prev] != arr[cur])
			swap(&arr[cur], &arr[prev]);

		cur++;
	}
	
	swap(&arr[keyi], &arr[prev]);
	keyi = prev;
	
	//接下来就是递归
	//标准值左右两边
	QuickSort(arr, left, keyi - 1);
	QuickSort(arr, keyi + 1, right);

}

4.归并排序 

4.1归并排序 

归并排序,如其其名,先归,指将数组进行一个划分将区间中只剩一个数,然后将这个区间与它相邻的区间进行比较,将两个区间的数据进行一个排序,插入到一个中间数组中。 

动图演示:

代码实现:

 //归并排序(递归版)
void MergeSort(int* arr, int num)

参数:指向数组首元素的指针,数组中元素的数量

//子函数(实现主要功能)(递归)
void _MergeSort(int* arr, int* tmp, int left, int right)

参数:指向数组首元素的指针,指向中间临时数组首元素的地址,指向数组最左边位置,指向数组最右边位置 

//子函数(实现主要功能)(递归)
void _MergeSort(int* arr, int* tmp, int left, int right)
{

	//区间中只有一个数直接跳出循环
	if (left >= right)
		return;


	int middle = (left + right) / 2 ;
	//左区间
	_MergeSort(arr, tmp, left, middle);
	//右区间
	_MergeSort(arr, tmp, middle+1, right);

	int begin1 = left, begin2 = middle + 1;
	int end1 = middle, end2 = right;
	int i = begin1;


	//一次比较
	while (begin1<=end1&&begin2<=end2)
	{
		//将小的数放数组中
		if (arr[begin1] < arr[begin2])
			tmp[i++] = arr[begin1++];
		else
			tmp[i++] = arr[begin2++];

	}

	//循环左右两个数组一个又一个读取完成
	while (begin1 <= end1)
	{
		tmp[i++] = arr[begin1++];
	}

	while (begin2 <= end2)
	{
		tmp[i++] = arr[begin2++];
	}

	//将调序的结果复制到原数组中
	memcpy(arr + left, tmp + left, sizeof(int) * (right - left + 1));

}





//归并排序(递归版)
void MergeSort(int* arr, int num)
{
	int* tmp = (int*)malloc(sizeof(int) * num);
	if (tmp == NULL)
	{
		perror("MergeSort::malloc");
		exit(1);
	}

	//调用子函数
	_MergeSort(arr, tmp, 0, num-1);

	//释放空间
	free(tmp);
	tmp = NULL;

}

//归并排序(非递归)
void MergeSortNonR(int* arr, int num) 

//子函数(非递归)
void _MergeSortNonR(int* arr, int* tmp, int left, int right)

//子函数(非递归)
void _MergeSortNonR(int* arr, int* tmp, int left, int right)
{
	

	int gap = 1;
	int n = right - left + 1;

	while (gap<n)
	{
		for (int j = left; j <=right;j=j+2*gap )
		{
			int begin1 = j, begin2 = j + gap;
			int end1 = j + gap - 1, end2 = j + 2*gap - 1;
			int i = j;

			//数组越界的问题
			//[begin1 end1]和[begin2 end2]


			//对应于end1大于n和begin2  > n的情况
			if (begin2 > right)
				break;
			//对应end2 > n 的情况
			if (end2 > right)
			{
				end2 = right;
			}


			//一次比较
			while (begin1 <= end1 && begin2 <= end2)
			{
				//将小的数放数组中
				if (arr[begin1] < arr[begin2])
					tmp[i++] = arr[begin1++];
				else
					tmp[i++] = arr[begin2++];

			}

			//循环左右两个数组一个又一个读取完成
			while (begin1 <= end1)
			{
				tmp[i++] = arr[begin1++];
			}

			while (begin2 <= end2)
			{
				tmp[i++] = arr[begin2++];
			}

			//将调序的结果复制到原数组中
			memcpy(arr + j, tmp + j, sizeof(int)* (end2-j+1));

		}

		gap = 2 * gap;


	}

}


//归并排序(非递归)
void MergeSortNonR(int* arr, int num)
{
	int* tmp = (int*)malloc(sizeof(int) * num);
	if (tmp == NULL)
	{
		perror("MergeSort::malloc");
		exit(1);
	}

	//调用子函数
	_MergeSortNonR(arr, tmp, 0, num - 1);

	//释放空间
	free(tmp);
	tmp = NULL;
}

gap是一个区间差,区间差成倍数的增加,这样最终会出现一个越界的情况,每一次会分为连个区间 [begin1  end1]  [begin2  end2]  begin1是不可能越界的,越界的可能是end1 begin2 和end 2

end1越界:说明end1,begin2和end2都是越界的。这也就是说只有一个区间是有效区间,那么就不需要两个区间进行比较,直接退出。

begin2越界:这个情况和end1越界是一样的,只有一个有效区间,可以直接退出。

end2越界,说明有两个区间,一个区间有效,一个区间部分有效,end2越界说明它大于数组的最左边的位置,那么那个部分有效的区间中的有效区间实际上就是[begin2  right],直接将end2赋值为rigth,就可以进行两个区间的比较。

 总结 

         上面介绍了几种常见的数据结构的排序方法,一些排序的理解是比较复杂的,所以需要自己画相应的图,一步一步的推演排序的过程。同时有什么错误或者问题可以在评论区进行交流。 

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

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

相关文章

VXLAN技术

VXLAN技术 一、VXLAN简介 1、定义 VXLAN&#xff08;Virtual eXtensible Local Area Network&#xff09;&#xff1a;采用MAC in UDP&#xff08;User Datagram Protocol&#xff09;封装方式&#xff0c;是NVO3&#xff08;Network Virtualization over Layer 3&#xff09…

机器学习算法 —— 贝叶斯分类之模拟离散数据集

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 目录 实战&#xff08;贝叶斯分类&#xff09;莺尾花数据模拟离散数据集库函数导入数据导入和分析模型训练和预测 总结 实战&#xff08;贝叶斯…

C语言 | Leetcode C语言题解之第144题二叉树的前序遍历

题目&#xff1a; 题解&#xff1a; int* preorderTraversal(struct TreeNode* root, int* returnSize) {int* res malloc(sizeof(int) * 2000);*returnSize 0;if (root NULL) {return res;}struct TreeNode *p1 root, *p2 NULL;while (p1 ! NULL) {p2 p1->left;if (…

一道Delphi的For循环题目

起因 事情是这样的&#xff1a; 俺在一个Delphi交流QQ群&#xff0c;有点冷场&#xff0c;俺想热一下场子就发了下面这个段子。其实这是之前俺带新人时的一道题目。 第一个回答 第一个网友给的答案是 i:i-1; 俺说这个答案是不对的&#xff0c;因为 Delphi在编译时是不允许…

探索智慧机场运营中心解决方案的价值与应用

随着全球航空业的不断发展&#xff0c;机场运营中心的作用日益凸显。智慧机场运营中心解决方案以其高效的管理和智能化的运营模式&#xff0c;成为优化机场运营、提升服务水平的重要工具。本文将深入探讨智慧机场运营中心解决方案的价值与应用&#xff0c;揭示其在机场管理中的…

软件下载网站源码附手机版和图文教程

PHP游戏应用市场APP软件下载平台网站源码手机版 可自行打包APP&#xff0c;带下载统计&#xff0c;带多套模板&#xff0c;带图文教程&#xff0c;可以做软件库&#xff0c;也可以做推广app下载等等&#xff0c;需要的朋友可以下载 源码下载 软件下载网站源码附手机版和图文…

下拉框数据被遮挡 且 后续数据无法下拉的 解决方法

目录 前言1. 问题所示2. 原理分析3. 解决方法3.1 添加空白版2.2 调整z-index2.3 父容器的溢出属性2.4 调整样式属性4. 效果图前言 小程序使用的是Uniapp,原理都差不多,索性标题就不标注Uniapp(小程序) 对于该问题调试了一个晚上,最终解决,对此记录下来 1. 问题所示 执…

怎么取消Intellij IDEA中的项目和Git仓库的关联

这篇文章分享一种最简单的方法&#xff0c;取消已经开启代码控制的项目与git代码仓库的关联。 打开项目的位置&#xff0c;然后点击文件管理器上方的查看选项卡&#xff0c;勾选【隐藏的项目】。 删除.git文件夹 然后可以看到项目的文件夹下显示了一个隐藏的.git文件夹&#x…

MATLAB基础应用精讲-【数模应用】二元Logit分析

目录 算法原理 数学模型 极大似然法 Newton牛顿迭代法 logit回归分析步骤 一、二元logit分析 1.基本说明 2.数据处理 3.SPSSAU上传数据 4.分析前提示 5.SPSSAU分析 6.其它说明 二、多分类logit分析 1.基本说明 2.数据要求与处理 3.SPSSAU上传数据 4.SPSSAU分析…

微信小程序双层/多层 wx:for 循环嵌套,关于内外层的 index 和 item ;data-index 传递两个参数

微信小程序用 wx:for 循环可以快速将后端 js 的数组快速显示到前端&#xff1b; 那假如数组中嵌套数组&#xff1b;就存在内外层两层及以上的多层嵌套循环了。 那么如果两层的嵌套式循环 index 究竟是属于哪一层呢&#xff1f;item 又属于哪一个呢&#xff1f; <view><…

【优选算法】详解target类求和问题(附总结)

目录 1.两数求和 题目&#xff1a; 算法思路&#xff1a; 代码&#xff1a; 2.&#xff01;&#xff01;&#xff01;三数之和 题目 算法思路&#xff1a; 代码&#xff1a; 3.四数字和 题目&#xff1a; 算法思路&#xff1a; 代码&#xff1a; 总结&易错点&…

Java实现物候相机和植被分析导出相对指数成果图

一、基础概念 植被分析是利用地理信息系统&#xff08;GIS&#xff09;、遥感技术、生态学、环境科学等多学科交叉手段&#xff0c;对植被的分布、类型、结构、组成、动态变化、生产力、生态功能进行量化评估的过程。植被分析对于生态保护、生物多样性研究、资源管理、环境监测…

交易中的群体行为特征和决策模型

本文基于人的行为和心理特征&#xff0c;归纳出交易中群体的行为决策模型&#xff0c;并基于这个模型&#xff0c;分析股价波浪运行背后的逻辑&#xff0c;以及投机情绪的周期变化规律&#xff0c;以此指导交易&#xff0c;分析潜在的风险和机会&#xff0c;寻找并等待高性价比…

stm32MP135裸机编程:修改官方GPIO例程在DDR中点亮第一颗LED灯

0 参考资料 轻松使用STM32MP13x - 如MCU般在cortex A核上裸跑应用程序.pdf 正点原子stm32mp135开发板&原理图 STM32Cube_FW_MP13_V1.1.0 STM32CubeIDE v1.151 需要修改那些地方 1.1 修改LED引脚 本例使用开发板的PI3引脚链接的LED作为我们点亮的第一颗LED灯&#xff0c;…

教育的数字化转型——Kompas.ai如何变革学习体验

引言 在现代教育中&#xff0c;数字化转型逐渐成为提升学习效果的重要手段。随着科技的进步&#xff0c;人工智能&#xff08;AI&#xff09;在教育领域的应用越来越广泛。本文将探讨教育数字化转型的发展趋势&#xff0c;并介绍Kompas.ai如何通过AI技术变革学习体验。 教育数…

金融量化分析开源工具:TuShare

TuShare&#xff1a;一站式金融数据解决方案&#xff0c;让量化分析触手可及- 精选真开源&#xff0c;释放新价值。 概览 TuShare&#xff0c;是Github社区上一个专为金融量化分析师和数据爱好者设计的开源工具&#xff0c;提供了从数据采集、清洗加工到数据存储的全流程服务。…

element-plus的el-space标签的使用

el-space标签可以很方便的设置标签间距和分隔符&#xff0c;对齐方式&#xff0c;是否拆行等属性。 <script setup lang"ts"> import { onMounted, ref } from vue;const sizeref(30)</script><template><el-space wrap :size"size"…

Redis实战宝典:基础知识、实战技巧、应用场景及最佳实践全攻略

背景 在Java系统实现过程中&#xff0c;我们不可避免地会借助大量开源功能组件。然而&#xff0c;这些组件往往功能丰富且体系庞大&#xff0c;官方文档常常详尽至数百页。而在实际项目中&#xff0c;我们可能仅需使用其中的一小部分功能&#xff0c;这就造成了一个挑战&#…

c语言编程

1. 2。 int main(int argc, const char *argv[]) { int year,month,day; int result0; printf("请输入&#xff1a;"); scanf("%d/%d/%d",&year,&month,&day); if(month>12||month<1) { printf("error \n"); return 0; } s…

解决Vue项目Network: unavailable的问题

在vscode使用 npm run serve 运行 Vue项目时发现一个问题&#xff0c;项目只能通过Local访问而不能通过Network访问&#xff0c;终端显示如下&#xff1a; 碰到这种情况的解决方法&#xff1a;在环境变量的path中添加“C:\Windows\System32\Wbem” 1.找到“环境变量”&#xf…