考研算法笔记(排序)

本文主要探讨考研中涉及的内部排序算法,包括插入排序、交换排序、选择排序、归并排序和基数排序。详细讲解了各种排序算法的稳定性、适用场景、时间复杂度和空间复杂度,并给出了算法优化思路,如快速排序的非递归实现、荷兰国旗问题等。
摘要由CSDN通过智能技术生成

考纲

(只考虑内部排序)
1插入排序(直插(稳),希尔)
2交换排序(冒泡(稳),快排)
3选择排序(简选,堆排)
4归并排序(稳)
5基数排序(稳)
6算法笔记

对任意n个关键字排序的比较次数至少为log₂(n!)

1.插入排序

1.1.直接插入排序(稳定)
适合顺序表,也可适用于链表,所以两个都需实现
(用折半查找优化时,只能用顺序表!!!)

1.查找插入位置(外部大循环)//第一个元素总是有序的,从第二个开始比较
2.后移(内部小循环)
void InsertSort(ElemType A[],int n){	//顺序表实现直接插入排序
//1.第一步找插入位置
	for(int i=2;i<=n;i++){				//从第二个元素比较之前有序的序列,找到
		if(A[i]<A[i-1]){		//如果if一直不成立,则空循环n趟就完了,若if成立(存在一个数小于其前驱),则进行插入操作
			A[0]=A[i];			//哨兵暂存“待插入点”
			for(int j=i-1;A[0]<A[j];--j){	//在待插点之前的有序序列中查找位置
				A[j+1]=A[j];		//不断后移
			}
				A[j+1]=A[0];		//最后的位置为j+1,因为是--j,最后一次循环的时候减了1
		}// (if)
	} //(for)
}



折半优化查找可减少比较次数!!但不减少移动次数
void InsertSort(ElemType A[],int n){	//顺序表实现直接插入排序
//1.第一步找插入位置
	for(int i=2;i<=n;i++){				//从第二个元素比较之前有序的序列,找到
		if(A[i]<A[i-1]){		//如果if一直不成立,则空循环n趟就完了,若if成立(存在一个数小于其前驱),则进行插入操作
		
		(这个位置的代码改变,外面的大循环是不变的)
		1.由顺序查变为折半查,2.边查边后移变为,先查到再统一后移。
		
		}// (if)

	//为啥改进过的直插,还是O(n²)?这里看到两个for循环,外层大循环,套这里的移动小循环。
		for(j=i-1;j>=high+1;--j){			//找到位置了 就是 low或 high+1;
			A[j+1]=A[j];					//统一后移
		}
		 A[high+1]=A[0];   		//或  A[low]=A[0]
	} //(for)
}

具体代码
int low,high,mid;
A[0]=A[i];	
low=1;high=i-1;		//折半的范围是 从第一个到第i-1个(有序的序列)

while(low<=high){		//这个while+if 是由那个for转化来的,
	mid=(low+high)/2;
	if(A[mid]>A[0])
		high=mid-1;
	else
		low=high+1;
}





单链表实现
//需要声明三个指针,p(工作指针,大循环), pre(工作指针,小循环), r(暂存p的后继,防止断链)
void InsertSort(LinkList &L){
	LNode *p=L->next;
	LNode *pre,*r=p->next;	//这里的r存p->next,即初始时的第二个元素,p一会就把表搞断,先存着
	p->next=null;				//为什么p后继赋值null?表示只有一个数据,肯定有序࿰
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值