408计算机考研--数据结构--排序模板(C语言)

数据结构–排序模板(C语言)

1.插入排序–直接插入排序(稳定的排序算法)

//折半插入排序--稳定排序。
//时间复杂度:最好情况下:O(n)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void InsertSort3(int* A,int numSize){
	int i,j,low,high,mid,temp;
	for(int i=1;i<numSize;i++){
        //找到前有序序列的当前数的插入位置
        temp=A[i];
        low=0,high=i-1;
		while(low<=high){
			mid=(low+high)/2;
			if(A[mid]>temp){
				high=mid-1;
			}else{
				low=mid+1;
			}
		}
        //插入
		for(int j=i-1;j>=high+1;j--){
			A[j+1]=A[j];
		}
		A[high+1]=temp;
	}
}
//插入排序2--稳定排序。
//时间复杂度:最好情况下:O(n)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void InsertSort2(int* A,int numSize){
	for(int i=1;i<numSize;i++){
        	//找到位置后再插入
			int temp=A[i];
			int j=i;
			while(j-1>=0&&temp<A[j-1]){
				A[j]=A[j-1];
				j-=1;
			}
			if(j!=i){
				A[j]=temp;
			}
	}
}
//插入排序1--稳定排序。
//时间复杂度:最好情况下:O(n)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void InsertSort(int* A,int numSize){
	for(int i=1;i<numSize;i++){
		for(int j=i-1;j>=0;j--){
			if(A[j]>A[j+1]){//交换
				A[j+1]=A[j+1]^A[j];
				A[j]=A[j+1]^A[j];
				A[j+1]=A[j+1]^A[j];
			}
		}
	}
}

2.插入排序–希尔排序(不稳定的排序算法)

//希尔排序优化。
//时间复杂度:最好情况下:O(n^1.3)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void XierSort(int* A,int numSize){
	for(int d=numSize/2;d>0;d/=2){//取步长
		for(int i=d;i<numSize;i++){//遍历步长
            //交换法
			for(int j=i-d;j>=0;j-=d){
					if(A[j+d]<A[j]){
						A[j+d]=A[j+d]^A[j];
						A[j]=A[j+d]^A[j];
						A[j+d]=A[j+d]^A[j];
					}
			}
		}
	}
}
//希尔排序优化。
//时间复杂度:最好情况下:O(n^1.3)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void XierSort2(int* A,int numSize){
	for(int d=numSize/2;d>0;d/=2){//取步长
		for(int i=d;i<numSize;i++){//遍历步长
            //插入法
			int temp=A[i];
			int j=i;
			while(j-d>=0&&temp<A[j-d]){
				A[j]=A[j-d];
				j-=d;
			}
			if(j!=i){
				A[j]=temp;
			}
		}
	}
}

3.交换排序–冒泡排序(稳定的排序算法)

//冒泡排序。
//时间复杂度:最好情况下:O(n)。最坏情况下:O(n^2);
//空间复杂度:O(1)
void BubbleSort(int* A,int numSize){
	bool flag;//判断是否已经有序
	for(int i=0;i<numSize-1;i++){
		flag=false;
		for(int j=numSize-1;j>i+1;j--){//冒泡
			if(A[j]<A[j-1]){//交换
				A[j]=A[j]^A[j-1];
				A[j-1]=A[j]^A[j-1];
				A[j]=A[j]^A[j-1];
				flag=true;
			}
		}
		if(!flag){
			return;
		}
	}
}

4.交换排序–快速排序(不稳定的排序算法)

//分治
int Partition(int* A,int low,int high){
	int standard=A[low];//基准值
	while(low<high){//根据基准值划分数组
		while(low<high&&A[high]>=standard) high--;//从左找比基准值小的数
		A[low]=A[high];
		while(low<high&&A[low]<=standard) low++;//从右找比基准值大的数
		A[high]=A[low];
	}
	A[low]=standard;
	return low;
}
//快速排序。
//时间复杂度:最好情况下:O(nlogn)。最坏情况下:O(nlogn);
//空间复杂度:O(logn)
void QuickSort(int *A,int low,int high){
	if(low<high){
		int partition=Partition(A,low,high);//枢轴
		QuickSort(A,low,partition-1);//枢轴左排序
		QuickSort(A,partition+1,high);//枢轴右排序
	}	
}

5.选择排序–简单选择排序(不稳定的排序算法)

 //选择排序。
 //时间复杂度最好情况下:O(n^2)。最坏情况下:O(n^2);
 //空间复杂度:O(1)
 void SelectSort(int* A,int numSize){
 	int min;//记录最小值下标 
 	for(int i=0;i<numSize-1;i++){
 		min=i;//最小值的下标 
 		for(int j=i+1;j<numSize;j++){
 			if(A[j]<A[min]){
 				min=j;
			 }
		 }
		 if(min!=i){//交换
		 	A[min]=A[i]^A[min];
		 	A[i]=A[i]^A[min];
		 	A[min]=A[i]^A[min];
		 }
	 }
 }

6.选择排序–堆排序(不稳定的排序算法)

void Swap(int* A,int i,int j){
	A[i]=A[j]^A[i];
	A[j]=A[j]^A[i];
	A[i]=A[j]^A[i];
}
//数组大根堆化
void Heapify(int* A,int n,int i){
	int c1=2*i+1;//左子结点 
	int c2=2*i+2;//右子结点
	int max=i;//根结点
	if(c1<n&&A[max]<A[c1]){//判断根节点与左子结点的大小
		max=c1;
	}
	if(c2<n&&A[max]<A[c2]){//判断根节点与右子结点的大小
		max=c2;
	}
	if(max!=i){
		Swap(A,max,i);//交换数组的两个元素 
		Heapify(A,n,max);//递归向下heapify 
	}
} 
//建堆
void BuildMaxHeap(int* A,int n){
	for(int i=(n-1)/2;i>=0;i--){
		Heapify(A,n,i);
	}
}
//堆排序。
//时间复杂度:最好情况下:O(nlogn)。最坏情况下:O(nlogn);
//空间复杂度:O(1)
void HeapSort(int* A,int n){
	BuildMaxHeap(A,n);//建堆
	for(int i=n-1;i>0;i--){
		Swap(A,0,i);
		Heapify(A,i,0);
	} 
}	

7.归并排序(稳定的排序算法)

#include<stdio.h>
#include<stdlib.h>

int *auk;
void Merge(int* A,int low,int mid,int high){
	int i=low,j=mid+1,k;
	for(k=low;k<=high;k++){//复制数组的值到辅助数组
		auk[k]=A[k];
	} 
	for(k=low;k<=high;k++){//左右区间的数比较
		if(i>mid){//左区间数用完,则取右区间的数
			A[k]=auk[j++];
		}else if(j>high){//右区间数用完,则取左区间的数
			A[k]=auk[i++];
		}else if(auk[i]>auk[j]){//左区间当前数大于右区间当前数,则取右区间的数
			A[k]=auk[j++];
		}else{//右区间当前数大于左区间当前数,则取左区间的数
			A[k]=auk[i++];
		}
	} 
}
//归并排序。
//时间复杂度:最好情况下:O(nlogn)。最坏情况下:O(nlogn)
//空间复杂度:O(n)
void MergeSort(int* 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);//合并左右区间
	}
}
int main(){
	int A[]={1,3,2,7,4,9,6,8,5};
	auk=(int *)malloc(sizeof(int)*9);//给辅助数组分配空间 
	MergeSort(A,0,8);//归并排序
	for(int i=0;i<9;i++){
		printf("%d ",A[i]);
	}
} 

8.基数排序(稳定的排序算法)

//基数排序(数组实现):
//注意:基数排序的数组不能有负数 
//时间复杂度:最好情况下:O(d(n+r))。最坏情况下:O(d(n+r))
//空间复杂度:O(nr)
void BaseSort(int* A,int numSize){
	if(numSize<=1) return;
	//取得数组中最大的数
	int max=0;
	for(int i=0;i<numSize;i++){
		if(max<A[i]){
			max=A[i];
		}
	}
	//取得最大数的位数
	int maxDight=1;
	while(max/10>0){
		maxDight++;
		max/=10;
	} 
	//申请一个桶空间
	int buckets[10][numSize];
	int base=10;//位 
	
	
	//从高位到低位进行桶排序 
	for(int i=0;i<maxDight;i++){
		//存储各个桶中存储元素的数量
		int bktLen[numSize];
		for(int i=0;i<numSize;i++){
			bktLen[i]=0;
		}
		
		//分配
		for(int j=0;j<numSize;j++){
			//获取当前位数字大小
			int whichBucket=(A[j]%base)/(base/10);
			//分配进对应数字大小的桶中
			buckets[whichBucket][bktLen[whichBucket]]=A[j]; 
			bktLen[whichBucket]++;
		} 
		
		//收集:从低位到高位将不同桶中的数据挨个取出来,为下一轮高位排序做准备
		int k=0;
		for(int b=0;b<10;b++){
			for(int p=0;p<bktLen[b];p++){
				A[k++]=buckets[b][p];
			}
		} 
		base*=10;
	} 
	 
}

若用链表实现:
时间复杂度:最好情况下:O(d(n+r))。最坏情况下:O(d(n+r))
空间复杂度:O(r)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值