冒泡排序:
最简单的一种排序,重复的遍历数列,每次比较两个元素,按一定的顺序排列;
for(int i=0;i<ength;i++)//length是数组的长度 { for(int j=0;j<length-1-i;j++) { if(a[j]>a[j+1]) swap(a[j],a[j+1]); } }
选择排序:
在未排序的序列中寻找最大(小)元素,存放在起始位置,在剩下未排序的再寻找最大(小)的,直到所有元素排序完成;
for(int i=0;i<10;i++) { int max=i; for(int j=i+1;j<10;j++) { if(a[max]<a[j]) max=j; } swap(a[max],a[i]); }
插入排序:
将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面)。
for(int i=1;i<10;i++)//下标元素从1开始,因为下标为0的只有一个元素,默认有序 { int tmp =a[i];//待插入的数 int j=i; while(j>0&&tmp<a[j-1])//遍历是否存在满足条件的数 { a[j]=a[j-1]; j--; } if(j!=i)//存在,插入 a[j]=tmp; }
希尔排序:
选择一个增量序列 t1,t2,……,tk,其中 t1 > t2, tk = 1;
按增量序列个数 k,对序列进行 k 趟排序;
每趟排序,根据对应的增量 ti,将待排序列分割成若干长度为 m 的子序列,分别对各子表进行直接插入排序。仅增量因子为 1 时,整个序列作为一个表来处理,表长度即为整个序列的长度。
void shell(int arr[],int len)
{
if(arr==NULL||len==1)
return;
int div=len/2;
while(div)
{
for(int i=0;i<div;i++)
{
for(int j=i;j<len-div;j=j+div)
{
for(int k=j;k<len;k=k+div)
if(arr[k]>arr[j])
swap(arr[k],arr[j]);
}
}
div=div/2;
}
}
int shellSort(int arr[], int len) { int gap = len / 2; while (gap > 0) {// 分组直接插入排序 for (int i = 0; i < len - gap; i++) { int j = i + gap; int tmp = arr[j]; while (j >= gap && tmp < arr[j - gap]) { arr[j] = arr[j - gap]; j -= gap; } arr[j] = tmp; } gap/=2; } return 0; }
归并排序
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
void Merge(int a[], int left, int mid, int right)
{
int len = right - left + 1; // 数组的长度
int *temp = new int[len];
int k = 0;
int i = left;
int j = mid + 1;
while (i <= mid && j <= right)
{
temp[k++] = a[i] <= a[j] ? a[i++] : a[j++];
}
while (i <= mid)
{
temp[k++] = a[i++];
}
while (j <= right)
{
temp[k++] = a[j++];
}
for (int k = 0; k < len; k++)
{
a[left++] = temp[k];
}
}
// 递归实现的归并排序
void MergeSort(int a[], int left, int right)
{
if (left == right)
return;
int mid = (left + right) / 2;
MergeSort(a, left, mid);
MergeSort(a, mid + 1, right);
Merge(a, left, mid, right);
}
快速排序:
从数列中挑出一个元素,称为 “基准”(pivot);
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
void Qsort(int a[], int low, int high) { if(low >= high) { return; } int first = low; int last = high; int key = a[first];/*用字表的第一个记录作为枢轴*/ while(first < last) { while(first < last && a[last] >= key) { --last; } a[first] = a[last];/*将比第一个小的移到低端*/ while(first < last && a[first] <= key) { ++first; } a[last] = a[first]; /*将比第一个大的移到高端*/ } a[first] = key;/*枢轴记录到位*/ Qsort(a, low, first-1); Qsort(a, first+1, high); }
堆排序
堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
大顶堆:每个节点的值都大于或等于其子节点的值,在堆排序算法中用于升序排列;
小顶堆:每个节点的值都小于或等于其子节点的值,在堆排序算法中用于降序排列;
void PercDown(int A[], int i, int N) { int child; ElementType Tmp; for (Tmp = A[i]; 2*i+1 < N; i = child){ child = 2*i+1; //注意数组下标是从0开始的,所以左孩子的求发不是2*i if (child != N - 1 && A[child + 1] > A[child]) ++child; //找到最大的儿子节点 if (Tmp < A[child]) A[i] = A[child]; else break; } A[i] = Tmp; } void HeapSort(int A[], int N) { int i; for (i = N / 2; i >= 0; --i) PercDown(A, i, N); //构造堆 for(i=N-1;i>0;--i) { Swap(&A[0],&A[i]);//将最大元素(根)与数组末尾元素交换,从而删除最大元素,重新构造堆 PercDown(A, 0, i); } }