常见排序算法(下)

2023-11-05

目录

1.交换排序

1.1交换排序的基本思想

1.2冒泡排序

 1.3快速排序

1.3.1Hoare

1.3.2挖坑法

1.3.3 针对性的优化

 1.3.4前后指针法

 *1.3.5非递归实现快速排序

2.归并排序

 2.1递归实现归并排序

 2.2非递归(迭代)实现归并排序

 *3.内排序和外排序

4.计数排序

5.总结

5.1表格比较

 5.2各种排序的稳定性


1.交换排序

1.1交换排序的基本思想

基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

1.2冒泡排序

在这里插入图片描述

基本思想

以升序为例,每一趟的冒泡排序都是把一个最大的数放到最后面,如果 a[i-1]>a[i],我们将i-1,i的值进行交换,依次循环反复。

 

void BubbleSort(int* a, int n){
    
    for(int j=0; j<n; j++){
        int flag = 0;
        for(int i=1; i<n-j; ++i){
            if(a[i] < a[i-1] ){
                Swap(&a[i], &a[i-1]);
                flag = 1;
            }
        }
        if(flag == 0){
            break;
        }
    }
}

 时间复杂度:

最坏的情况:O(N^2)

最好的情况:O(N)

 冒泡排序和插入排序相比,顺序有序一样好,接近有序时插入排序更好

 1.3快速排序

1.3.1Hoare

在这里插入图片描述

 快速排序是Hoare1962年提出的一种二叉树结构的交换排序方法,其基本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止

 基本思想:

选一个关键key,一般都是选择头。
单趟:key放在他正确的位置上,key的左边值比key小,key右边值比key大(这是key一趟下来排完后最终要放的位置)
单趟拍完,再想办法让左边区间有序,key的右边区间有序

 

 

 

 

 

 最后相遇的位置和关键字key进行交换

 下面实现快速排序中的单趟排序

void QuickSort(int* a, int n)
{
	int left = 0, right = n - 1;
	int keyi = left;
	while(left < right)
	{
		while (a[right] >= a[keyi])
		{
			--right;
		}
		while (a[left] <= a[keyi])
		{
			++left;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);
}

 上述代码在下面极端情况下出现越界的问题->加一个判断即可

 

void QuickSort(int* a, int n)
{
	int left = 0, right = n - 1;
	int keyi = left;
	while(left < right)
	{
		while (left<right && a[right] >= a[keyi])
		{
			--right;
		}
		while (left<right && a[left] <= a[keyi])
		{
			++left;
		}
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);
}

 注意:若不加等号会在下列情况出现死循环

 

 下面实现多趟排序

 

void QuickSort(int* a,int begin, int end)
{
	if (begin >= end)
		return;
	
	int left = 0, right = end - 1;
	int keyi = left;
	while(left < right)
	{
		while (left<right && a[right] >= a[keyi])
		{
			--right;
		}
		while (left<right && a[left] <= a[keyi])
		{
			++left;
		}
		Swap(&a[left], &a[right]);
	}
	int meeti = left;

	Swap(&a[keyi], &a[left]);

	//[begin,meeti-1]meeti[meeti+1,end];
	QuickSort(a, begin, meeti - 1);
	QuickSort(a, meeti+1, end);
}

 将单趟排序单独写出来

int PartSort(int* a, int left, int right)
{
	int keyi = left;
	while (left < right)
	{
		while (left < right && a[right] >= a[keyi])
			--right;
		while (left < right && a[left] <= a[keyi])
			++left;
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);

	return left;
}

void QuickSort2(int* a, int begin, int end)
{
	if (begin >= end)
		return;

	int keyi = PasrSort(a, begin, end);

	//[begin,meeti-1]meeti[meeti+1,end];
	QuickSort(a, begin, keyi - 1);
	QuickSort(a, keyi + 1, end);
}

对于单趟排序的思考为什么相遇位置的值一定比key小?为什么key选择最左边的值,就要先让右边的数先走先去找小?

为了确保最后相遇时的a[left]<a[key],只要让右边的数先走,最后停下来时无论是“左边遇到右边”还是“右边遇到左边”,都满足a[left]<a[key]。

 一个单趟进行的排序操作的时间复杂度是多少?思考下一次完整的快排需要进行多少趟这样的单趟排序?

一个单趟的时间复杂度是O(N),一个完整的快排需要O(logN)趟这样的单趟排序

1.3.2挖坑法

在这里插入图片描述

 基本思想

挖坑法可以选择在0索引处挖坑(即把数拿走保存),然后从右边找一个小的填坑,再从左边找一个大的埋住右边的坑,以此反复循环,直到left与right相遇,最后把key放入相遇点(最后一个坑位)即可

 

 

 

 

 

 

 

 

 

 

 

 虽然也实现了左边比key小,右边比key大,但是数字的顺序和通过单趟排序实现的不同

 

int PartSort2(int* a, int left, int right)
{
	int key = a[left];
	while (left < right)
	{
		//找小
		while (left < right && a[right] >= key)
		{
			--right;
		}
		
		//放到左边的坑位中,右边就形成新的坑
		a[left] = a[right];

		//找大
		while (left < right && a[left] <= key)
		{
			++left;
		}

		//放到右边的坑位中,左边就形成新的坑
		a[right] = a[left];
	}

	a[left] = key;

	return left;
}

对于时间复杂度的分析

 

1.3.3 针对性的优化

分析:对快排影响最大的是选的key,key越接近中位数越接近二分,效率越高

三数取中

小区间优化 

int GetMidIndex(int* a, int left, int right)
{
	int mid = (left + right) >> 1;
	//left mid right
	if (a[left] < a[mid])
	{
		if (a[mid] < a[right])
		{
			return mid;
		}
		else if (a[left] > a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
	else//a[left]>a[mid]
	{
		if (a[mid] > a[right])
		{
			return mid;
		}
		else if (a[left] < a[right])
		{
			return left;
		}
		else
		{
			return right;
		}
	}
}
int PartSort1(int* a, int left, int right)
{
	int midIndex = GetMidIndex(a, left, right);
	Swap(&a[left], &a[midIndex]);

	int keyi = left;
	while (left < right)
	{
		while (left < right && a[right] >= a[keyi])
			--right;
		while (left < right && a[left] <= a[keyi])
			++left;
		Swap(&a[left], &a[right]);
	}
	Swap(&a[keyi], &a[left]);

	return left;
}

 进行“三数取中”的意义是什么?

如果我们不进行“三数取中”,快排如果遇见最坏的情况——有序,时间复杂度将会变成O(N^2),如果加了“三数取中”,这一最坏情况将会不复存在(后边俩种单趟排序同理)。

 1.3.4前后指针法

基本思想

1.cur往前走,找到比key小的数据

2.找到比key小的数据以后,停下来,++prev

3.交换prev和cur指向位置的值

直到cur到达最右边的位置结束!

 cur还没遇到比key大的数据之前,prev紧跟着cur,cur遇到比key大的值以后,prev和cur之间间隔着一段比key大的数据。

 

 ++prev

交换 

 以此类推得

 

 

 实现单趟排序

int PartSort3(int* a, int left, int right)
{

    //三数取中
	int midIndex = GetMidIndex(a, left, right);
	Swap(&a[left], &a[midIndex]);

	int keyi = left;
	int prev = left, cur = left + 1;
	while (cur <= right)
	{
		if (a[cur] < a[keyi] && a[++prev] != a[cur])//cur遇到比key小的值后:++prev,且防止自己和自己交换
		{
			Swap(&a[cur], &a[prev]);
		} 

		++cur;
	}
	Swap(&a[keyi], &a[prev]);

	return prev;
}

 实现多趟排序(添加小区间优化)

void QuickSort(int* a, int begin, int end)
{
	if (begin >= end)
		return;
	
	//1.如果这个子区间是数据较多,继续选key单趟,分割子区间分治递归
	//2.如果这个子区间是数据较小,再去分治递归不太划算
	if (end - begin > 20)
	{
		int keyi = PartSort3(a, begin, end);

		//[begin,keyi-1]keyi[keyi+1,end]
		QuickSort(a, begin, keyi - 1);;
		QuickSort(a, keyi + 1, end);
	}
	else
	{
		InsertSort(a+begin+1,end-begin+1);
	}
}

 

 *1.3.5非递归实现快速排序

递归,现代编译器优化很好,性能已经不是大问题
最大的问题:递归深度太深,程序本身没问题,但是栈空间不够,导致栈溢出
只能改成非递归,改成非递归两种方式
1.直接改成循环->斐波那契数列的求解
2.树遍历非递归和快排非递归等等,只能有Stack存储数据魔力递归过程

void QuickSortNonR(int* a, int begin, int end)
{
	Stack st;
	StackInit(&st);
	StackPush(&st, begin);
	StackPush(&st, end);

	while (!StackEmpty(&st))
	{
		int left, right;
		right = StackTop(&st);
		StackPop(&st);

		left = StackTop(&st);
		StackPop(&st); 

		int keyi = PartSort1(a, left, right);//单趟排序
		if (left < keyi - 1)
		{
			StackPush(&st, left);
			StackPush(&st, keyi - 1);
		}

		if (keyi + 1 < right)
		{
			StackPush(&st, keyi + 1);
			StackPush(&st, right);
		}
	}
    StackDestory(&st);
}

2.归并排序

在这里插入图片描述

基本思想:
归并排序( MERGE-SORT )是建立在归并操作上的一种有效的排序算法 , 该算法是采用分治法( Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

 2.1递归实现归并排序

 

 

  

void _MergeSort(int* a, int left, int right,int* tmp)
{
	if (left >= right)//当区间只存在一个值的时候或者区间不存在时返回
		return;

	int mid = (left + right) >> 1;
	_MergeSort(a, left, mid, tmp);
	_MergeSort(a, mid + 1, right, tmp);

	//两端有序子区间归并tmp,并拷贝回去
	int begin1 = left, end1 = mid;
	int begin2 = mid + 1, end2 = right;
	int i = left;
	while (begin1<=end1 && begin2<=end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
			tmp[i++] = a[begin2++];
	}

	while(begin1 <= end1)
		tmp[i++] = a[begin1++];

	while (begin2 <= end2)
		tmp[i++] = a[begin2++];
	
	//归并完成以后,拷贝回到原数组。
	for (int j = left; j <= right; ++j)
		a[j] = tmp[j];
}

void MergeSort(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}
	_MergeSort(a, 0, n - 1,tmp);
	
	free(tmp);
}

 

 

时间复杂度

O(NlogN),可以看出他的递归过程中每次都将一组平均分,分完后高度大概是logN,空间复杂度O(N)

 2.2非递归(迭代)实现归并排序

基本思想

迭代实现可以用循环来实现,这里我们根据递归思想其实很容易知道,我们控制迭代从最小的子问题出发,保存最小子问题的值,然后提供给后面用,这其实就是一个动态规划的思想,我们可以从利用子问题的解,解决 “大BOSS” 。

 

 两两一归

 

 最后将tmp拷贝回到原数组

 void _Merge(int* a,int* tmp, int begin1, int end1,int begin2,int end2)
{
	int j = begin1;
	int i = begin1;
	while (begin1 <= end1 && begin2 <= end2)
	{
		if (a[begin1] < a[begin2])
		{
			tmp[i++] = a[begin1++];
		}
		else
			tmp[i++] = a[begin2++];
	}

	while (begin1 <= end1)
		tmp[i++] = a[begin1++];

	while (begin2 <= end2)
		tmp[i++] = a[begin2++];

	//归并完成以后,拷贝回到原数组
	for (int j = begin1; j <= end2; ++j)
		a[j] = tmp[j];

}
void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	int gap = 1;//用于控制数据个数
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			//[i,i+gap-1][i+gap,i+2*gap-1]
			_Merge(a, tmp, i, i + gap - 1, i + gap, i + 2 * gap - 1);
		}
		gap *= 2;
	}
	free(tmp);	  
}

 

两两一归的时候没问题

在下列几种情况时候出现问题

 或者改正(利用条件断点找出问题

void MergeSortNonR(int* a, int n)
{
	int* tmp = (int*)malloc(sizeof(int) * n);
	if (tmp == NULL)
	{
		printf("malloc fail\n");
		exit(-1);
	}

	int gap = 1;
	while (gap < n)
	{
		for (int i = 0; i < n; i += 2 * gap)
		{
			//[i,i+gap-1][i+gap,i+2*gap-1]
			//如果第二个小区间不存在就不需要归并,结束本次循环
			int begin1 = i, end1 = i + gap - 1, begin2 = i + gap, end2 = i + 2 * gap - 1;
			if (i + gap >= n)
				break;
			//如果第二个小区间存在,但是第二个小区间不够gap个,结束位置越界了,需要修正一下
			if (end2 >= n)
				end2 = n - 1;
			_Merge(a,tmp,begin1,end1,begin2,end2);
		}
		gap *= 2;
	}
	free(tmp);	  
}
归并排序的特性总结:
1. 归并的缺点在于需要 O(N) 的空间复杂度,归并排序的思考更多的是解决在磁盘中的外排序问题。
2. 时间复杂度: O(N*logN)
3. 空间复杂度: O(N)
4. 稳定性:稳定

 *3.内排序和外排序

 

 

 

4.计数排序

在这里插入图片描述

基本思想

1.统计原数组中每个值出现的次数

2.排序:遍历Count数组,对应位置的值出现多少次就往原数组写几个这个值

当然,在对于数据比较大的时候我们可以通过相对映射,让(该值-min)后的数组加一,最后还原回去即可。

 


void CountSort(int* a, int n)
{
	int max = a[0], min = a[0];
	for (int i = 0; i < n; i++)
	{
		if (a[i] > max)
			max = a[i];
		if (a[i] < min)
			min = a[i];
	}

	int range = max - min + 1;
	int* count = malloc(sizeof(int) * range);
	memset(count, 0, sizeof(int) * range); 

    //计数
	for (int i = 0; i < n; i++)
	{
		count[a[i] - min]++; 
	}

    //排序
	int i = 0;
	for (int j = 0; j < range; j++)
	{
		while (count[j]--)
		{
			a[i++] = j + min;
		}
	}

	free(count);
}

 

时间复杂度

计数排序的时间复杂度是O(N+range),只适合一组数据。数据的范围比较集中。如果范围集中,效率很高,并且只适合整数,如果是浮点数、字符串等等就不行了。空间复杂度是O(max-min),即为O(range),就是我们开的数组是这个区间的范围差。

5.总结

5.1表格比较

 

image-20211017193628979

 5.2各种排序的稳定性

冒泡排序:俩俩对比,前一个大于后一个才发生交换(升序),不会出现相等值互换顺序的情况,能保证不改变相同值的相对顺序,稳定。

简单选择排序:在进行俩数交换位置的过程当中,可能数组当中有一个数跟发生交换的俩数数值是一样的,这样就改变的相同数之间的相对顺序,不稳定。

直接插入排序:从前到后一个个元素拿出来跟前面的对比,若插入的数值比被对比的数值小,被对比的数值往后挪动;若插入的数值比被对比的数值大,直接插入到被对比数值的后面,并没有改变俩个相同值得相对顺序,稳定。

希尔排序:在预排序时,相同的数据可能在不同的组里面,没办法控制,所以不稳定。

堆排序:比如俩个一样大的数值,一个在“树顶”,一个在“树中”,树顶元素跟最后一个元素发生交换立马影响相同数值的相对顺序,不稳定。

归并排序:能保证相同值得相对顺序不变,稳定。

快速排序:比如数组中存在跟key数值一样的值,而key是肯定会移动的,这样相对顺序就改变了,所以不稳定。

计数排序:计数是在统计每个数出现的次数,但是相同的数哪个在前哪个在后,并没有区分,所以不稳定。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

常见排序算法(下) 的相关文章

  • 在 OpenCL 中将函数作为参数传递

    是否可以在 OpenCL 1 2 中将函数指针传递给内核 我知道可以用C实现 但不知道如何在OpenCL的C中实现 编辑 我想做这篇文章中描述的同样的事情 在 C 中如何将函数作为参数传递 https stackoverflow com q
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • ZLIB 解压缩

    我编写了一个小型应用程序 该应用程序应该解压缩以 gzip deflate 格式编码的数据 为了实现这一点 我使用 ZLIB 库 使用解压缩功能 问题是这个功能不起作用 换句话说 数据不是未压缩的 我在这里发布代码 int decompre
  • 为什么密码错误会导致“填充无效且无法删除”?

    我需要一些简单的字符串加密 所以我编写了以下代码 有很多 灵感 来自here http www codeproject com KB security DotNetCrypto aspx create and initialize a cr
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • gdb查找行号的内存地址

    假设我已将 gdb 附加到一个进程 并且在其内存布局中有一个文件和行号 我想要其内存地址 如何获取文件x中第n行的内存地址 这是在 Linux x86 上 gdb info line test c 56 Line 56 of test c
  • 如何检测 C# 中该字典键是否存在?

    我正在使用 Exchange Web 服务托管 API 和联系人数据 我有以下代码 即功能性的 但并不理想 foreach Contact c in contactList string openItemUrl https service
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • Swagger 为 ASP.CORE 3 中的字典生成错误的 URL

    当从查询字符串中提取的模型将字典作为其属性之一时 Swagger 会生成不正确的 URL 如何告诉 Swagger 更改 URL 中字典的格式或手动定义输入参数模式而不自动生成 尝试使用 Swashbuckle 和 NSwag 控制器 pu
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12

随机推荐

  • Heroku 部署有关 opencv 的 Django 后端应用(pdf2docx)

    文章目录 场景 解决方案 Aptfile Buildpacks Dashboard 上手动构建 Heroku CLI 终端构建 Requirements txt 提交改变 场景 我使用 heroku 部署了一个 Django 后端项目 里面
  • C/C++内存布局

    下图是c c 的进程的内存分布布局图 搞清楚内存布局对于理解一个程序是非常重要的 一个程序运行起来 操作系统会给每个进程分配一个 4G 的程序地址空间 当然这都是虚拟地址空间 因为如果一个进程分 4G 的内存 那么就算有再多的内存也不够分
  • windows下的另一个辅助工具Devcon.exe(用会了绝对是神器)

    Device Console Help devcon exe r m
  • Unity3D关于iTween回调函数

    ITween一共三个回调函数 onstart onupdate和oncomplete 顾名思义可以从名字中看出来 常用到最后一个 要是我以后项目中用到了前两个函数 我会把例子添加上 关于oncomplete 就是在itween移动完成以后所
  • Spring Data Jpa

    spring data介绍 Spring Data s mission is to provide a familiar and consistent Spring based programming model for data acce
  • 单元测试、集成测试、系统测试

  • 串口通信——发送和接收数据(8位和16位数据之间的转换)

    1 实验目的 1 发送两个字节数据 就是16位的数据 每一次发送8位 发送两次 这里要进行数据的拆分 如发送一个0XFF56 接收得到的也是FF56 16进制显示 2 接收两个字节的数据 这里通过串口助手以16进制发送一个数据 将拼接的数据
  • winMain函数

    WinMain函数 int WINAPI WinMain HINSTANCE hInstance HINSTANCE hPrevInstance LPSTR lpCmdLine int nShowCmd 函数名 WinMain 返回值 in
  • QT界面工程导出成dll并在其他界面工程调用示例

    一 首先是生成dll 1 新建一个qt工程 2 在 pro文件做如下修改 TARGET qtdll TEMPLATE app DEFINES dllMainWindow LIBRARY TEMPLATE lib 其中qtdll 是自己dll
  • C#中Dictionary的用法总结

    可以实现通过键值查找 插入 删除一个键 值对的操作 这些如果用数组实现都非常麻烦 Key就是键 value就是值 我们在很多地方都会用到字典 他的特点就是查找很快 当然比List快 字典必须包含名空间System Collection Ge
  • pandas写入excel指定行_使用pandas操作excel

    pandas操作excel 最近由于要处理一些excel表格 发现pandas可以免去很多的繁琐的人工劳动 在这里记录一下我所用到的知识 导入文档 将excel中的工作表导入 filename xls data pd read excel
  • python中random.random()用法

    Python中的random模块用于生成随机数 下面介绍一下random模块中最常用的几个函数 random random random random 用于生成一个0到1的随机符点数 0 lt n lt 1 0 参考链接 https www
  • 拓扑布局和建立小型网络

    练习 2 6 1 拓扑布局和建立小型网络 地址表 本实验不包括地址表 拓扑图 学习目标 正确识别网络中使用的电缆 物理连接点对点交换网络 验证每个网络的基本连通性 简介 许多网络问题都可以在网络的物理层解决 因此 必须清楚了解网络连接使用哪
  • Android ffmpeg4.1 arm64位库裁剪

    ffmpeg4 1 Android arm64位库裁剪移植 目录 ffmpeg4 1 Android arm64位库裁剪移植 1 绪言 2 编译环境 3 源代码下载 4 编写编译脚本 4 1 编译脚本 4 2 常见问题 5 库裁剪 5 1
  • 使用vscode把代码或文件夹上传进gitee库里

    1 首先读者自行下载 git 2 在gitee中新建一个仓库 3 建完仓库后会出现以下界面 4 复制图中1 选择你个你想要的文件夹 右键选择 5 之后会跳出来一个小框框 把图中2和3分别复制进小框框里 ctrl v没用 右键选择Paste
  • CObject/CCmdTarget/CCmdTarget三个类的能力

    三个类的能力分别为 CObject 运行时类型识别 RTTI 动态创建 Dynamic Creation 文件读写 Serialization CCmdTarget 消息机制 拥有DECLARE MESSAGE MAP宏 从而可以接收WM
  • 二十二、SQL 数据分析实战(案例1~案例10)

    文章目录 案例1 用户信息表 stu table 案例2 员工绩效表 score table 案例3 销售冠军信息表 month table 案例4 月销售额记录表 sale table 案例5 每季度员工绩效得分表 score info
  • Kubernetes 入门 篇 Master 节点的安装与部署

    在安装K8s 的时候 遇到了很多问题 花了几天的时间排错 记录一下环境搭建的完整过程 希望对入门K8s 的朋友有所帮助 操作系统版本 CentOS Linux 8 Docker 版本 Docker version 23 0 1 运行 Kub
  • 迷茫

    读了两年的软件工程 迷茫始终伴随着自己的前行道路 我想吃计算机这碗饭 我又不想吃太久 这个问题我都感觉很吃屎 大一刚开始 学的是C语音 老师就是按着书本的知识给你讲 数据类型 函数 控制语句 数组 指针 文件 讲完之后 这些东西还是这些东西
  • 常见排序算法(下)

    目录 1 交换排序 1 1交换排序的基本思想 1 2冒泡排序 1 3快速排序 1 3 1Hoare 1 3 2挖坑法 1 3 3 针对性的优化 1 3 4前后指针法 1 3 5非递归实现快速排序 2 归并排序 2 1递归实现归并排序 2 2