【数据结构】排序算法研究合集

0.排序算法总论

算法设计要点

  1. 等号有没有的问题
    有没有等号,关键看项目需求,关注算法的本质含义
    例如:对于“折半查找方式” 允许low=high;
    对于“保证元素数量>=2”则不允许low=high

1.排序算法的核心思想

核心思想

  1. 定位、遍历、递归【注意递归成立的前提条件】
  2. 比较
  3. 移动
  4. 特殊情况

核心关注点

  1. 关于“=”
  2. 关于“+1,0,-1”

2.插入排序

2.1.直接插入排序

/*基于线性表,从小到大排序*/
//直接插入排序【第5次】
bool InsertSort(int a[],const int &n)
{
	if(n <= 0)
		return false;

	for(int i = 1;i < n;i++)
	{
		if(a[i] < a[i-1])
		{
			int j = i-1;
			int tmp = a[i];
			while(j >= 0 && tmp < a[j])//【思维纠正】tmp小,就往前走,直到不小为止
			{
				a[j+1] = a[j];
				j--;
			}
			a[j+1] = tmp;
		}
	}
	return true;
}

2.2.折半插入排序

//折半插入排序
bool BinInsertSort(int a[],const int &n)
{
	if(n <= 0)
		return false;

	for(int i = 1;i < n;i++)
	{
		if(a[i] < a[i-1])
		{
			int low = 0,high = i-1,mid;
			int tmp = a[i];
			while(low <= high)
			{
				mid = (low+high)/2;
				if(tmp < a[mid])
					high = mid-1;
				else
					low = mid+1;
			}
			for(int j = i-1;j > high;j--)
				a[j+1] = a[j];
			a[high+1] = tmp;
		}
	}
	return true;
}

2.3.希尔排序

当d=1的时候,“希尔排序”退化为“标准直接插入排序”

原始数据

int a[] = {9,5,4,38,1,2,20,21};
int len = sizeof(a)/sizeof(a[0]);

备注:输出的是每一趟的结果
i += 1是正确写法,标准的希尔排序
i++是正确写法,是希尔排序,但是写的时候产生了一个错误,写成了i += d,这样是什么结果呢?

i += d 的情况
这样的话,基本上跟“直接插入排序”没有什么区别了,因为d=1的时候交换次数最多

【希尔排序的本质】:尽可能地减少d = 1时候的交换次数,d越大,交换地越多,这样才能减少总体交换时间(这里谈及的是n!不是个例!)
拓展:用内部折半插入进行排序希尔排序(内部折半插入)

3.交换排序

3.1.冒泡排序

3.1.1.关键字:循环,锁定

3.2.快速排序

3.2.1.关键字

  1. 一次划分
  2. 递归(分治思想,自上而下)

3.2.2.一句话

符合移动,不符不动,相等均符合

3.2.3.算法描述&算法本质

3.2.4.算法实现:算法一

【注意】本算法的易错点:“tmp >= a[i] <= a[j]”,一定要加上“=”,否则会进入无限比较(例如 4,6,7,1,4 会在4…4无限比较4,但就是不能移动)

//快速排序
int partition(int a[],int low,int high)//一次划分
{
	if(low < 0 || high < 0)
		return false;

	int i = low,j = high;
	int tmp = a[i];
	while(i < j)
	{
		while(i < j && tmp <= a[j])//注意等号
			j--;
		a[i] = a[j];
		while(i < j && tmp >= a[i])//注意等号
			i++;
		a[j] = a[i];
	}
	a[i] = tmp;
	return i;
}

bool QuickSort(int a[],int low,int high)//递归调用划分
{
	if(low < 0 || high < 0)
		return false;

	if(low < high)
	{
		int i = partition(a,low,high);
		QuickSort(a,low,i-1);
		QuickSort(a,i+1,high);
	}
	return true;
}

3.2.5.算法评价

3.2.5.1.时间复杂度分析

3.2.5.2.空间复杂度分析

3.2.5.3.稳定性分析

3.2.5.4.应用分析

3.2.6.算法实战

对于大量数据,算法需要进行优化,否则会因为“递归深度过高”导致“堆栈溢出”,算法失效!

4.选择排序

4.1.简单选择排序

4.1.1.关键字:循环,锁定

4.2.堆排序

5.归并排序

关键字:
  • 一次归并
  • 递归(分治思想,自上而下)
核心算法
  1. 递归调用,不断拆分,直到每个有序表都只有一个元素
  2. 对每两个有序表合并
  3. 递归返回,重复2过程
  4. 得出结果
核心函数
  1. Merge 一次归并函数
  2. MergeSort 归并函数

6.基数排序

发布了7 篇原创文章 · 获赞 2 · 访问量 934

猜你喜欢

转载自blog.csdn.net/weixin_42929607/article/details/103651169
今日推荐