排序算法(复习自用)

插入排序

直接插入排序

//直接插入排序 
void InsertSort(int A[],int n ){
	int i,j,temp;
	for(i=1;i<n;i++){//将个元素插入到已排好序的序列中 这里与下文不同是因为没有哨兵 
		if(A[i]<A[i-1]){//若A[i]关键字小于前驱 
			temp = A[i];//用temp暂存A[i] 
			for(j = i-1; i>=0 && A[j]>temp;--j){//检查所有前面已经排好序的元素 
				A[j+1] = A[j];//所有大于temp的元素都向后挪位 
			}
			A[j+1] = temp;//复制到插入位置 
		}
	}
}

直接插入排序(带哨兵)

//直接插入排序(带哨兵) 
void Insert_Sort(int A[],int n){
	int i,j;
	for(i = 2;i <= n; i++){//注意i从2开始到n,是因为哨兵的原因,占了一个位置,不像上面的代码 
		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];
		}
	}
}

折半插入排序

//折半插入排序
void B_Insert_Sort(int A[],int n){
	int i,j,low,mid,high;
	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;//查找右半子表 
			}
		}
		for(j = i-1; j >= high + 1;j--){
			A[j+1] = A[j];//统一后移元素,空出插入位置 
		}
		A[high+1] = A[0];//插入操作 
	}
}

希尔排序

//希尔排序
void ShellSort(int A[],int n){
	int d,i,j;
	//A[0]只是暂存单元,不是哨兵,当j<=0时,插入位置已到
	for(d = n/2; d >= 1; d = d/2 ){
		for(i=d+1;i<=n;i++){//这里开始与直接插入排序类似(像带哨兵与不带哨兵的结合) 
			if(A[i]<A[i-d]){
				A[0] = A[i];
				for(j=i-d; j>0 && A[0] < A[j]; j-=d){//(判断部分与直接插入排序有区别,其他地方类似)
					A[j+d]=A[j];
				}
				A[j+d] = A[0];
			}
		}
	} 
} 

交换排序

交换函数

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

冒泡排序

//冒泡排序
void BubbleSort(int A[],int n){
	for(int 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 == false){
			return;//本趟遍历后没有交换,说明表已经有序 
		}
	}
} 

快速排序

//用第一个元素将待排序序列分成左右两个部分
int Partition(int A[],int low,int high){
	int pivot = A[low];//第一个元素作为枢轴 
	while(low<high){//用low、high搜索枢轴的最终位置 
		while(low<high&&A[high]>=pivot){
			high--;
		}
		A[low] = A[high];//比枢轴小的元素移动到左端 
		while(low<high&&A[low]<=pivot){
			low++;
		}
		A[high] = A[low];//比枢轴大的元素移动到右端 
	}
	A[low] = pivot;//枢轴元素存放到最终位置 
	return low;//返回存放枢轴的最终位置 
} 

//快速排序
void QuickSort(int A[],int low,int high){
	if(low<high){//递归跳出的条件 
		int pivotpos = Partition(A,low,high);//划分 
		QuickSort(A,low,pivotpos-1);//划分左子表 
		QuickSort(A,pivotpos+1,high);//划分右子表 
	}
} 

选择排序

交换函数

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

简单选择排序

//简单选择排序
void SelectSort(int A[],int n){
	for(int i = 0; i < n-1; i++){
		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]);
		}
	}
} 

堆排序

//堆排序
//将以k为根的子树调整为大根堆
void HeadAdjust(int A[],int k,int len){
	A[0] = A[k];//A[0]暂存子树的根节点 
	for(int i = 2*k;i<=len;i*=2){//沿key较大的子结点向下筛选 
		if(i<len&&A[i]<A[i+1]){
			i++;//取key较大的子结点的下标 
		}
		if(A[0]>=A[i]){
			break;//筛选结束 
		}else{
			A[k] = A[i];//将A[i]调整到双亲节点上 
			k = i;//修改k值,以便继续向下筛选 
		}
	}
	A[k] = A[0];//被筛选结点的值放入最终位置 
} 



//建立大根堆
void BuildMaxHeap(int A[],int len){
	for(int i = len/2;i>0;i--){
		HeadAdjust(A,i,len);//从后往前调整所有非终端节点 
	}
} 


//堆排序的完整逻辑
void HeadSort(int A[],int len){
	BuildMaxHeap(A,len);//初始建堆 
	for(int i = len;i>1;i--){//n-1趟的交换和建堆过程 
		swap(A[i],A[1]);//堆顶元素和堆底元素交换 
		HeadAdjust(A,1,i-1);//把剩余的待排序元素整理成堆 
	}
} 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值