C语言实现几种常见排序算法

1.冒泡法 


冒泡排序最好的时间复杂度为 O(n)。
冒泡排序总的平均时间复杂度为 O(n^2)


冒泡排序算法的原理如下:
1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2.对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
3.针对所有的元素重复以上的步骤,除了最后一个。(比较 n-1 趟,每趟 n-1-i 次)
4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

void BubbleSort(int arr[],int n)
{
	for(int i=0;i<n-1;++i)
	{
		for(int j=0;j<n-1-i;++j)
		{
			if(arr[j] > arr[j+1])
			{
				int tmp = arr[j];
				arr[j] = arr[j+1];
				arr[j+1] = tmp;
			}
		}
	}
}

2.直接快速排序


第一趟比较前两个数,然后把第二个数按大小插入到有序表中; 
第二趟把第三个数据与前两个数从后向前扫描,把第三个数按大小插入到有序表中;
依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。

直接插入排序是由两层嵌套循环组成的。外层循环标识并决定待比较的数值。
内层循环为待比较数值确定其最终位置。直接插入排序是将待比较的数值与它的前一个数值进行比较,
所以外层循环是从第二个数值开始的。当前一数值比待比较数值大的情况下继续循环比较,
直到找到比待比较数值小的并将待比较数值置入其后一位置,结束该次循环。

//方法一
void InsertSort_1(int arr[],int n)
{
    for(int i=1;i<n;i++)//循环从第2个元素开始
    {
        if(arr[i] < arr[i-1])
        {
            int temp=arr[i];
            for(int j=i-1;j>=0 && arr[j]>temp;j--)
                arr[j+1]=arr[j];
            arr[j+1]=temp;
		}
    }
}
//方法二
//a[0]哨兵位,假设a[1]已为排好序的,开始排序  //打印从arr[1]开始
void InsertSort_2(int arr[],int n)
{
	for(int i=2;i<n;++i)
	{
		if(arr[i] < arr[i-1])
		{
			arr[0] = arr[i];
			arr[i] = arr[i-1];
			for(int j=i-1;arr[0]<arr[j-1];--j)
				arr[j] = arr[j-1];
			arr[j] = arr[0];
		}
	}
}

3. 折半插入排序

在将一个新元素插入已排好序的数组的过程中,寻找插入点时,将待插入区域的首元素设置为a[low],
末元素设置为a[high],则轮比较时将待插入元素与a[m],其中m=(low+high)/2相比较,如果比参考元素小,
则选择a[low]到a[m-1]为新的插入区域(即high=m-1),否则选择a[m+1]到a[high]为新的插入区域(即low=m+1),
如此直至low<=high不成立,即将此位置之后所有元素后移一位,并将新元素插入a[high+1]

void BinSort(int arr[],int n)
{
	for(int i=2;i<=n;i++)
	{
		arr[0]=arr[i];
		int low=1; 
		int high=i-1;
		while (low<=high)
		{	
			int mid=(low+high)/2;
			if(arr[0]<arr[mid])
			high=mid-1;
			else
			low=mid+1;
		}
		for(int j=i-1;j>=low;j--)
		{
			arr[i]=arr[j];
			i--;
		}
		arr[low]=arr[0];
	} 
	arr[0] = NULL;
}

4.希尔排序

希尔排序属于插入类排序,是将整个有序序列分割成若干小的子序列分别进行插入排序。
排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;
然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。

void shellSort(int arr[],int n)
{
 if(n<=1|| arr==NULL)
  return;
 for(int div=n/2;div>=1;div=div/2)//定增量div,并不断减小
 {
  for(int i=0;i<=div;++i)//分组成div组
  {
   for(int j=i;j<n-div;j+=div)//对每组进行插入排序
    for(int k=j;k<n;k+=div)
     if(arr[j]>arr[k])
	 {
		 int tmp = arr[j];
		 arr[j] = arr[k];
		 arr[k] = tmp;
	 }  
  }
 }
}

 5.快速排序

//快速排序
void Qsort(int arr[], int low, int high)
{
    if(low >= high)
    {
        return;
    }
    int first = low;
    int last = high;
    int key = arr[first];/*用字表的第一个记录作为枢轴*/
 
    while(first < last)
    {
        while(first < last && arr[last] >= key)
        {
            --last;
        }
 
        arr[first] = arr[last];/*将比第一个小的移到低端*/
 
        while(first < last && arr[first] <= key)
        {
            ++first;
        }
         
        arr[last] = arr[first];    
/*将比第一个大的移到高端*/
    }
    arr[first] = key;/*枢轴记录到位*/
    Qsort(arr, low, first-1);
    Qsort(arr, first+1, high);
}

 6.直接选择排序


第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,
与R[1]交换,....,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,
总共通过n-1次,得到一个按排序码从小到大排列的有序序列。

void SelectSort(int arr[], int n) 
{
    for (int i = 0; i < n - 1; i++) 
	{
        int m = i;
        for (int j = i + 1; j < n; j++)
		{
            if (arr[j] < arr[m]) 
				m = j;
            if (m != i) 
			{
            int tmp = arr[i];
            arr[i] = arr[m];
            arr[m] = tmp;
			}
        }
    }
}

 7.堆排序

//堆排序
void swap(int *a, int *b);
void adjustHeap(int param1,int j, int inNums[]);
void  HeapSort(int nums, int inNums[]);
//大根堆进行调整
void adjustHeap(int param1, int j, int inNums[])
{
    int temp=inNums[param1];
    for (int k=param1*2+1;k<j;k=k*2+1)
    {
        //如果右边值大于左边值,指向右边
        if (k+1<j && inNums[k]< inNums[k+1])
        {
            k++;
        }
        //如果子节点大于父节点,将子节点值赋给父节点,并以新的子节点作为父节点(不用进行交换)
        if (inNums[k]>temp)
        {
            inNums[param1]=inNums[k];
            param1=k;
        }
        else
            break;
    }
        //put the value in the final position
    inNums[param1]=temp;
}
//堆排序主要算法
void HeapSort(int nums,int inNums[])
{
    //1.构建大顶堆
    for (int i=nums/2-1;i>=0;i--)
    {
                //put the value in the final position
        adjustHeap(i,nums,inNums);
    }
    //2.调整堆结构+交换堆顶元素与末尾元素
    for (int j=nums-1;j>0;j--)
    {
                //堆顶元素和末尾元素进行交换
        int temp=inNums[0];
        inNums[0]=inNums[j];
        inNums[j]=temp;
 
        adjustHeap(0,j,inNums);//重新对堆进行调整
    }
}

 

 8、归并排序

//归并排序
void Merge(int sourceArr[],int tempArr[], int startIndex, int midIndex, int endIndex)
{
    int i = startIndex, j=midIndex+1, k = startIndex;
    while(i!=midIndex+1 && j!=endIndex+1)
    {
        if(sourceArr[i] > sourceArr[j])
            tempArr[k++] = sourceArr[j++];
        else
            tempArr[k++] = sourceArr[i++];
    }
    while(i != midIndex+1)
        tempArr[k++] = sourceArr[i++];
    while(j != endIndex+1)
        tempArr[k++] = sourceArr[j++];
    for(i=startIndex; i<=endIndex; i++)
        sourceArr[i] = tempArr[i];
}
 
//内部使用递归
void MergeSort(int sourceArr[], int tempArr[], int startIndex, int endIndex)
{
    int midIndex;
    if(startIndex < endIndex)
    {
        midIndex = startIndex + (endIndex-startIndex) / 2;//避免溢出int
        MergeSort(sourceArr, tempArr, startIndex, midIndex);
        MergeSort(sourceArr, tempArr, midIndex+1, endIndex);
        Merge(sourceArr, tempArr, startIndex, midIndex, endIndex);
    }
}

 主函数(用于测试)

void main()
{
	int arr[] = {6,23,43,12,8,2,31,29};
	int n = sizeof(arr)/sizeof(int);
	//BubbleSort(arr,n);
	//InsertSort_1(arr,n);
	//InsertSort_2(arr,n);
	//BinSort(arr,n);
	//shellSort(arr,n);
    //Qsort(arr,0,n);
	//SelectSort(arr,n);
	 //HeapSort(n, arr);
	int brr[8];
	MergeSort(arr,brr, 0, n-1);
	for(int i=0;i<n;i++)
		printf("%d ",arr[i]);
	printf("\n");
}

#endif


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值