6种排序算法及其比较 简单选择排序,堆排序,简单插入排序,希尔排序,冒泡排序,快速排序,归并排序

简单选择排序:

/*
在未排序的序列中选出最小的元素和序列的首位元素交换,接下来在剩下的未排序的序列中再
选出最小的元素与序列的第二位元素交换 
*/
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
void sort(int n)
{
	int minn;
	for(int i=0;i<n-1;i++)
	{
		minn=i;
		for(int j=i+1;j<n;j++)
		{
			if(num[j]<num[minn])
			{
				minn=j;
			}
		}
		swap(num[i],num[minn]);
	}
}
int main()
{
	sort(10);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

堆排序:

/*
利用最大堆输出堆顶元素,即最大值,将剩余元素重新生成最大堆,继续输出堆顶元素,重
复这个过程,直到全部元素都输出。 
*/ 
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
void adjust(int i,int n)
{
	int child,temp;
	//将第i个依次跟后面的比较找到它应该放置的位置 
	for(temp=num[i];(2*i+1)<n;i=child)
	{
		child=(2*i+1);
		if(child!=n-1&&num[child]<num[child+1])child++;//选取最大的元素 
		if(temp<num[child])num[i]=num[child];
		else break;
	}
	num[i]=temp;
}
void heapsort(int n)
{
	//建立最大堆 
	for(int i=(n-1)/2;i>=0;i--)
	{
		adjust(i,n);
	}
	//从最后一个元素开始,每一个跟num[0]交换 ,换完之后继续调整 
	for(int i=(n-1);i>0;i--)
	{
		swap(num[i],num[0]);
		adjust(0,i);
	}
}
int main()
{
	heapsort(10);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

简单插入排序:

/*
将待排序的一组序列分为已经排好序的和未排序的两个部分,初始状态时,已排序序列只包
含第一个元素,此后将未排序序列中的元素逐一插入到已排好序的序列中。经过n-1次插入
后,未排序序列中元素个数为0,则排序完成。 
*/ 
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
void sort(int n)
{
	int tmp;
	for(int i=0;i<n;i++)
	{
		tmp=num[i];
		int j; 
		for(j=i;j>0&&tmp<num[j-1];j--)
		{
			num[j]=num[j-1];
		}
		num[j]=tmp;
	} 
}
int main()
{
	sort(10);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

希尔排序:

/*
将待排序的一组元素按照一定的间隔分成若干个序列,分别进行插入排序。开始时间隔比较
大,在每一轮排序中间隔逐渐减小,直到间隔变为"1",也就是最后一次进行了简单排序 
*/
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
int incre[4]={5,3,1};
void sort(int n,int m)//m指incre中包含m个增量 
{
	int increment,tmp; 
	for(int i=0;i<m;i++)
	{
		increment=incre[i];
		for(int j=increment;j<n;j+=increment)
		{
			tmp=num[j];
			for(int k=j;k-increment>=0;k-=increment)
			{
				if(tmp<num[k-increment])num[k]=num[k-increment];
				else break;
				num[k-increment]=tmp;
			}
		}//结束一趟排序 
	}
}
int main()
{
	sort(10,3);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

冒泡排序:

/*
一共进行n-1次循环,在第k次循环中,对从第一到第n-k个元素从前往后进行比较,每次比较
相邻的两个元素,如果前一个元素大于后一个元素,则两者交换位置,否则位置保持不变。 
*/
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
void sort(int n)
{
	bool flag;
	for(int i=n-1;i>=0;i--)
	{
		flag=false;
		for(int j=0;j<i;j++)
		{
			if(num[j]>num[j+1])
			{
				swap(num[j],num[j+1]);
				flag=true;
			}
		}
		if(flag==false)break;
	} 
}
int main()
{
	sort(10);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

快速排序:

/*
将未排序元素根据基准分为两个子序列,其中一个子序列的记录均大于基准,而另一个子序
列均小于基准,然后递归的对这两个子序列用类似的方法进行排序 
*/
#include<cstdio>
#include<iostream>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
void qsort(int low,int high)
{
	int pivot=num[low];
	int left=low,right=high;
	if(low>=high)return;
	swap(num[low],num[right]);//将基准与最后一个元素交换 
	while(1)
	{
		while(low<high&&pivot>=num[low])low++;
		while(low<high&&pivot<=num[high])high--;
		if(low<high)swap(num[low],num[high]);
		else break; 
	}
	swap(num[low],num[right]);//将基准换到正确的位置上 
	qsort(left,low-1);
	qsort(low+1,right);
}
int main()
{
	qsort(0,9);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}

归并排序:

/*
将大小为n的序列看成n个长度为1的序列,接下来,两个相邻的序列两两进行归并操作,
继续归并,最后剩下一个长度为N的序列 
*/
#include<cstdio>
#include<iostream>
#include<stdlib.h>
using namespace std;
int num[10]={9,24,5,2,3,1,6,8,10,7}; 
int tmp[10];
void merge(int start,int mid,int end)
{
    int *tmp = (int *)malloc((end-start+1)*sizeof(int));    // tmp是汇总2个有序区的临时区域
    int i = start;            // 第1个有序区的索引
    int j = mid + 1;        // 第2个有序区的索引
    int k = 0;                // 临时区域的索引
    while(i <= mid && j <= end)
    {
        if (num[i] <= num[j])
            tmp[k++] = num[i++];
        else
            tmp[k++] = num[j++];
    }
    while(i <= mid)//剩余元素 
        tmp[k++] = num[i++];
    while(j <= end)
        tmp[k++] = num[j++];
    // 将排序后的元素,全部都整合到数组a中。
    for (i = 0; i < k; i++)
        num[start + i] = tmp[i];
    free(tmp);
}
void msort(int left,int right)
{
	if(left<right)
	{
		msort(left,(left+right)/2);
		msort((left+right)/2+1,right);
		merge(left,(left+right)/2,right);
	}
}
int main()
{
	msort(0,9);
	for(int i=0;i<10;i++)
	{
		printf("%d ",num[i]);
	}
	return 0;
}



排序算法效率比较
排序方法平均时间复杂度最坏情况下时间复杂度额外空间复杂度稳定性
简单选择排序O(N^2)O(N^2)O(1)不稳定
直接插入排序O(N^2)O(N^2)O(1)稳定
冒泡排序O(N^2)O(N^2)O(1)稳定
希尔排序O(N^d)O(N^2)O(1)不稳定
堆排序O(Nlog2N)
O(Nlog2N)
O(1)不稳定  
快速排序O(Nlog2N)O(N^2)O(1)不稳定
归并排序O(Nlog2N)O(Nlog2N)O(N)稳定
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值