数据结构之排序

排序知识点思维导图

在这里插入图片描述

排序代码实现

一、插入排序

1. 直接插入排序

//从小到大排序
void InsertSort(ElemType A[],int n){
//直接插入排序
	int i,j;
	for(i=2;i<=n;i++){	//默认第一个元素排好序,从第二个元素开始一次往后排序
		//如果为递增序列直接后移看下一个元素;如果不为,则进行调整
		if(A[i]<A[i-1]){
			//将此元素复制为哨兵	
			A[0]=A[i];		
			//前面为已拍好序序列,从后往前查找待插入位置,边查边向后挪位,
			for(j=i-1;A[0]<A[j];--j)
				A[j+1]=A[j];		//边查边挪
			//直到待查元素小于有序列中的元素,即将待查元素插入查找到的位置
			A[j+1]=A[0];
	}
}

2. 折半插入排序

//从小到大排序
void InsertSort(ElemType A[],int n){
//折半插入排序
	int i,j,low,high,mid;
	for(i=2;i<=n;i++){	//依次将A[2]~A[n]插入到前面已拍好序序列
		A[0]=A[i];		//将A[i]暂存到A[0]
		low = 1;high = i-1;	//折半查找范围
		while(low<=high){
			mid = (low+high)/2;	//取中间点
			if(A[mid] > A[0])
				high = mid-1;	//查左子表
			else
				low = mid+1;	//查右子表
		}
		//折半查找停止后在low所指位置插入元素,即high+1
		for(j=i-1;j>=high+1;--j)
				A[j+1]=A[j];		//统一后移元素,空出插入位置
		A[high+1]=A[0];	//插入操作
	}
}

3. 希尔排序

void ShellSort(ElemType A[],int n){
//希尔排序,对顺序表做希尔排序,比直接插入排序有如下修改
//1.前后记录的增量是dk,不是1
//2.A[0]只是暂存单元,不是哨兵,当j<=0时,就是插入位置
	int i,j,dk;	//dk为步长
	for(dk = n/2;dk>=1;dk/2){	//步长变化
		for(i = dk+1;i<=n;++i){
			if(A[i]<A[i-dk]){		//需要将A[i]插入有序增量子表
				A[0] = A[i];	//暂存A[0]
				for(j = i-dk;j >0 && A[0]<A[j];j-=dk)
					A[j+dk]=A[j];	//记录后移,查找插入元素的位置
				A[j+dk]=A[0];	//插入元素
			}//if
		}
	}
}

二、交换排序

1. 冒泡排序

//交换
void swap(&a,&b){
	int temp = a;
	a = b;
	b = temp;
}

//从小到大排序 冒泡排序
void BubbleSort(ElemType A[],int n){
	for(i=0;i<n-1;i++){
		bool flag = false;	//本趟冒泡排序是够发生交换标志
		for(int j = n-1;j>i;j--)	//一趟冒泡过程
			if(A[j-1]>A[j]){	//逆序
				swap(A[j-1],A[j]);	//交换
				flag = true;	//本趟发生交换
			}
		if(flag == true)
			return;	//本趟遍历后没有发生交换说明表已经有序
	}
}

2. 快速排序

void QuickSort(ElemType A[],int low,int high){
//快速排序
	if(low<high){	//递归跳出条件
	//Partition()就是划分操作,将表A[low...high]划分为满足上述条件的两个子表
		int pivotpos = Partition(A,low,high);	//划分
		QuickSort(A,low,pivotpos-1);
		QuickSort(A,pivotpos+1,high);
	}
}
int Partition(ElemType A[],int low,int high){
	//一趟排序过程(划分算法)
	ElemType pivot = A[low];	//将当前表中第一个元素设为枢轴值,对表进行划分
	while(low < high){	//循环跳出条件
		while(low < high && A[high] >= pivot)
			--hihg;
		A[low] = A[high];	//将比枢轴值小的元素移动到左端
		while(low < high && A[low] <= pivot)
			++low;
		A[high]=A[low];	//将比枢轴值大的元素移动到右端
	}
	A[low] = pivot;	//将枢轴元素存放到最终位置
	return low;	//返回存放枢轴元素的位置
}

三、选择排序

1. 简单选择排序

void SelectSort(ElemType A[],int n){
//简单选择排序,从0开始存放元素
	for(int i = 0; i <n-1; i++){//一共进行n-1趟
		int min = i;	//记录最小元素
		for(int j = i+1 ;j < n;j++)	//选择最小元素
			if(A[j]<A[min])
				min = j;	//更新最小元素位置
		if(min != i)
			swap(A[i],A[min]);	//与第i个位置互换
	}
}

2. 堆排序

//建立大根堆
void BuildMaxHeap(ElemType A[],int len){	//从i = [n/2]~1,反复调整堆
	for(i = len/2 ; i>0;i--)
		AdjustDown(A,i,len);
}
void AdjustDown(ElemType A[],int k,int len){
//函数AdjustDown将元素k向下进行调整
	A[0] = A[k];	//A[0]暂存
	for(i = 2*k ;i<=len; i *=2){	//沿k较大的子节点向下筛选
		if(i<len && A[i]<A[i+1])
			i++;	//取k较大的子节点的下标
		if(A[0] >= A[i])	
			break;	//筛选结束
		else{
			A[k] = A[i];	//将A[i]调整到双亲节点上
			k = i;	//修改k值,以便继续向下筛选
		}
	}//for
	A[k] = A[0]; //被筛选结点的值放入最终位置
}
//堆排序算法
void HeapSort(ElemType A[], int len) {
//堆排序
	BuildMaxHeap(A, len);	//建立初始堆
	for(int i = len; i > 1; i--){ //n-1趟的交换和建堆过程
		swap(A[i],A[1]);//输出堆顶的元素(和堆底元素交换)
		AdjustDown(A, 1, i - 1);//整理,把剩余的i-1个元素整理成堆
	}
}
//向上调整堆的算法
void AdjustUp(ElemType A[],int k){//参数k为向上调整的结点,也为堆的元素个数
	A[0] = A[k];
	int i = k / 2;	//若结点值大于双亲结点,则将双亲结点下调,并继续向上比较
	while (i > 0 && A[i] < A[0]) {//循环退出条件
		A[k] = A[i];	//双亲结点下调
		k = i;
		i = k / 2;	//继续向上比较
	}//while
	A[k] = A[o];	//复制到最终位置
}

四、归并排序

ElemType *B = (ElemType *)malloc(n+1)*sizeof(ElemType));
//辅助函数B
void Merge(ElemType A[],int low,int mid,int high){
	//表的两端A[low...mid],A[mid+1...high]各自有序,将它们合并成一个有序表
	for(int k = low; k <= high; k++)
		B[k] = A[k];	//将A中所有元素复制到B中
	for(i = low,j = mid+1,k=i;i<=mid&&j<=high;k++){
		if(B[i]<=B[j])	//比较B的左右两段中的元素
			A[k]=B[i++];	//将较小值复制到A中
		else
			A[k]=B[j++];
	}//for
	while(i<=mid)
		A[k++]=B[i++];	//若第一个表未检测完,复制
	while(j<=high)
		A[k++]=B[j++];	//若第二个表未检测完,复制
}
void MergeSort(ElemType A[],int low,int high){
	if(low <high){
		int mid = (low + high)/2;	//从中间划分两个子序列
		MergeSort(A,low,mid);	//对左侧子序列进行递归排序
		MergeSort(A,mid+1,high);	//对右侧子序列进行递归排序
		Merge(A,low,mid,high);	//归并
	}
}

合集:
数据结构之线性表
数据结构之栈与队列
数据结构之串
数据结构之树与二叉树
数据结构之图
数据结构之查找
数据结构之排序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值