http://www.docin.com/p-614435589.html
http://www.docin.com/p-300941887.html
http://www.cnblogs.com/alexworks/articles/1847080.html
排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度
冒泡排序 O(n2) O(n2) 稳定 O(1)
快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n)递归
选择排序 O(n2) O(n2) 不稳定 O(1)
二叉树排序 O(n2) O(n*log2n) 不一定 O(n)
插入排序 O(n2) O(n2) 稳定 O(1)
折半插入排序 O(n2) O(n2) 稳定 O(1)
希尔排序 O O 不稳定 O(1)
堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)
归并排序 O(n*log2n) O(n*log2n) 稳定 O(n)//递归
基数排序 O(n) O(n) 稳定 O(n)
桶排序 O(n) O(n) 稳定 O(n)
插入排序
原理:将数组分为无序区和有序区两个区,然后不断将无序区的第一个元素按大小顺序插入到有序区中去,最终将所有无序区元素都移动到有序区完成排序。
直接插入:
void InsertSort(int *a,int n)
{
int j;
int temp;
for (int i=1;i<n;i++)
{
temp=a[i];
j=i;
while (j>0&&a[j-1]>temp)
{
a[j]=a[j-1];
j--;//查找与移动同时进行
}
a[j]=temp;
}
}
折半插入:
void BinaryInsertSort(int *a,int n)
{
int temp,low,mid,high;
for (int i=1;i<n;i++)
{
temp=a[i];
low=0;
high=i-1;
while (high>=low)//用对半查找
{
mid=(high+low)/2;
if (temp<a[mid])
{
high=mid-1;
}
else
{
low=mid+1;
}
}
for (int j=i;j>low;j--)//移动
{
a[j]=a[j-1];
}
a[low]=temp;//放在这个位置
}
}
希尔排序(插入):
先取一个整数k,把全部记录分成k个组,所有距离是k的看成一个组插入排序,然后
k=k/2;
void shellsort(int *a,int n)
{
int k=n/2;
while (k>=1)
{
for (int i=0;i<k;i++)//第i组,共有k组
{
for (int j=k+i;j<n;j+=k)//组内移动,每次k个单位
{
int temp=a[j];//记录要插入的值
int m=j;//记录该位置
while ((m-k)>=0&&temp<a[m-k])
{
a[m]=a[m-k];
m=m-k;
}
a[m]=temp;
}
}
k=k/2;
}
}
//冒泡排序
void BubbleSort(int *a,int n)
{
for (int i=0;i<n;i++)//控制比较次数
{
for (int j=1;j<n-i;j++)//从1开始
{
if (a[j-1]>a[j])
{
int temp=a[j-1];
a[j-1]=a[j];
a[j]=temp;
}
}
}
}
改进版http://blog.csdn.net/morewindows/article/details/6657829
void BubbleSort(int *a,int n)
{
Int k=n;
for (int j=1;j<k;j++)//从1开始
{
if (a[j-1]>a[j])
{
int temp=a[j-1];
a[j-1]=a[j];
a[j]=temp;
}
}
K--;
}
1. //冒泡排序3
2. void BubbleSort3(int a[], int n)
3. {
4. int j, k;
5. int flag;
6.
7. flag = n;
8. while (flag > 0)
9. {
10. k = flag;
11. flag = 0;
12. for (j = 1; j < k; j++)
13. if (a[j - 1] > a[j])
14. {
15. Swap(a[j - 1], a[j]);
16. flag = j;
17. }
18. }
19. }
20.
选择排序
选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了,因为只剩下它一个最大的元素了。那么,在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。比较拗口,举个例子,序列5 8 5 2 9, 我们知道第一遍选择第1个元素5会和2交换,那么原序列中2个5的相对前后顺序就被破坏了,所以选择排序不是一个稳定的排序算法。
void SelectSort(int *a,int n)
{
for (int i=0;i<n;i++)
{
int minnum=a[i];//初始记为最小值
int minposition=i;
for (int j=i+1;j<n;j++)//寻找后面的最小值
{
if (a[j]<minnum)
{
minnum=a[j];
minposition=j;
}
}
swap(a[minposition],a[i]);//当前位置与后面的最小值交换
}
}
快速排序
http://blog.csdn.net/morewindows/article/details/6684558
分析:数据结构p186.重要
当源文件有序时复杂度是o(n2).此时冒泡排序最好,无序时快速排序是最好的方法。
void QuickSort(int *a,int l,int r)
{
if (r<=l)
{
return;
}
int i=l;
int j=r;
int x=a[i];//a[l]即a[i]就是第一个坑
//挖坑填数
while (j>i)
{
// 从右向左找小于x的数来填a[i]
while (a[j]>=x&&j>i)
{
j--;
}
if (j>i)
{
a[i]=a[j];//a[j]填到a[i]中,a[j]就形成了一个新的坑
i++;
}
// 从左向右找大于或等于x的数来填a[j]
while (a[i]<x&&j>i)
{
i++;
}
if (j>i)
{
a[j]=a[i];//将a[i]填到a[j]中,a[i]就形成了一个新的坑
j--;
}
}
//退出时,i等于j。将x填到这个坑中。
a[i]=x;
//分治法
QuickSort(a,l,i-1);
QuickSort(a,i+1,r);
}
//桶式排序 http://blog.csdn.net/hyhyl1990/article/details/7610279
#define N 10 //N表示要排序数组的数字个数
#define M 89 //M表示要排序元素中的最大值(元素值从0到M)
void bucketSort(int arr[],int n) //缺点:浪费了一大块内存
{
int Times[M+1]={0};//每个数对应一个桶,该数组存放每个桶的数字个数。初始为0
int TempArr[N];
for (int i=0;i<n;i++)//统计各数字出现的次数
{
Times[arr[i]]++;
}
//重新组织存放出现次数的数组 ,Times[i]-1是第i个桶的右边界索引 ,
for (int i=1;i<M+1;i++)
{
Times[i]+=Times[i-1];
}
//相同的数字位于同一个桶内,按照先后进入桶内的顺序根据该桶索引依次减小存放进该桶。
for (int i=n-1;i>=0;i--)//为了排序稳定性,从后面开始
{
TempArr[--Times[arr[i]]]=arr[i];
}
for (int i=0;i<n;i++)
{
arr[i]=TempArr[i];
}
}
//基式排序,原理同上,但是没有存在浪费内存的问题,按个位数排,然后再按十位数排。。。类似于扑克牌排序
void radixSort(int arr[],int n,int cou) //n表示数组内元素个数,cou表示位数
{
int radix=10;//十进制,共有10个数
int* tempArr=new int[n]; //开辟一个临时数组
int Times[10]={0}; //存放进制内各数出现的次数
int rad=1; //动态变化的基数
int Temp;
for (int i=0;i<cou;i++)//先从个位数开始,从低位到高位,依次进行判定
{
//一轮判定开始时,需要对times数组重置为0
for(int j=0;j<radix;j++)
{
Times[j]=0;
}
for (int j=0;j<n;j++)
{
Temp=(arr[j]/rad)%10;// //需要得到正在判定的这一位上的值
Times[Temp]++;
}
//对times数组进行重置
for (int j=1;j<10;j++)
{
Times[j]+=Times[j-1];
}
//对原数组内的元素进行收集,放在临时数组中。(从后面开始)
for (int j=n-1;j>=0;j--)//为了排序稳定性,从后面开始
{
Temp=(arr[j]/rad)%10;// //需要得到正在判定的这一位上的值
tempArr[--Times[Temp]]=arr[j];
}
//把临时数组tempArr内的元素复制到arr数组中
for (int j=0;j<n;j++)
{
arr[j]=tempArr[j];
}
rad*=radix; //该趟循环结束,rad=rad*radix
}
}
堆与堆排序
http://blog.csdn.net/morewindows/article/details/6709644
// 从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2
void MinHeapFixdown(int a[], int i, int n)
{
int j, temp;
temp = a[i];
j = 2 * i + 1;
while (j < n)
{
if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的
j++;
if (a[j] >= temp)
break;
a[i] = a[j]; //把较小的子结点往上移动,替换它的父结点
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
//由数组建立最小堆
void MakeMinHeap(int a[], int n)
{
for (int i = n / 2 - 1; i >= 0; i--)
MinHeapFixdown(a, i, n);
}
void Swap(int &a,int &b)
{
int temp=a;
a=b;
b=temp;
}
//堆排序
void Minheapsort(int a[], int n)
{
MakeMinHeap(a,n);//由数组建立二叉堆
for (int i = n - 1; i >= 1; i--)
{
Swap(a[i], a[0]);
MinHeapFixdown(a, 0, i);
}
}
归并排序
http://blog.csdn.net/morewindows/article/details/6678165
//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i=first;
int n=mid;
int j=mid+1;
int m=last;
int k=0;
while (i<=n&&j<=m)
{
//比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数
if (a[i]<a[j])
{
temp[k++]=a[i++];
}
else
{
temp[k++]=a[j++];
}
}
//有数列为空,那直接将另一个数列的数据依次取出即可
while (i<=n)
{
temp[k++]=a[i++];
}
while (j<=m)
{
temp[k++]=a[j++];
}
for (i=0;i<k;i++)
{
a[first+i]=temp[i];
}
}
void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左边有序
mergesort(a, mid + 1, last, temp); //右边有序
mergearray(a, first, mid, last, temp); //再将二个有序数列合并
}
}
排序最全总结
最新推荐文章于 2023-08-21 14:57:06 发布