您的位置:首页 > 编程语言 > C语言/C++

排序算法C++

2016-04-11 10:50 465 查看

排序算法C++

排序算法有很多种,为了更好的巩固知识,在这里和大家一起分享,有些的不对的地方还请指出来~~

选择排序

主要思想是每次找出最小的元素的索引和位置,与当次扫描的开始的数交换,比如说循环两次后,前两个数一定是该数组中最小的两个。代码如下:

void sort1(int a[], int n)
{
int small;
int smallindex;
int temp;
for (int i = 0; i < n;i++)
{
smallindex = i;
small = a[smallindex];
for (int j = i+1; j < n; j++)
{
if (a[j]<small)
{
smallindex = j;
small = a[j];
}
}
if (smallindex!=i)
{
temp = a[i];
a[i] = small;
a[smallindex] = temp;
}
}
}


选择排序是不稳定排序,比如说5 8 5 3 9,第一次,3和5交换位置。

- 冒泡排序

两个两个比较,每次都将最大的数放在最后面。程序如下:

void sort2(int a[], int n)
{
int temp;
for (int i = 0; i < n;i++)
{
for (int j = 0; j < n-i-1;j++)
{
if (a[j+1]<a[j])
{
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
}


冒泡排序是稳定排序,两个相等的数不会交换。

插入排序

插入排序就像打扑克牌一样,先抓一张,比如7,再抓一张4,你就会很自然的的排到7前面,这样依次排好就可以了。代码如下:

void sort3(int a[], int n)
{
int temp;
for (int i = 1; i < n;i++)
{
int j = i;
int temp = a[j];
while (temp<a[j-1])
{
a[j] = a[j - 1];
j--;
}
a[j] = temp;
}
}


插入排序也是稳定排序,还是抓扑克牌的道理。

- 快速排序

快速排序算法的思想是:先以第一个元素出发,总右边找到第一个比它小的数,从左边找到第一个比它大的数,然后二者交换,然后继续从右边和左边寻找,直到左边>=右边(索引),然后把第一个元素与右边索引所指的值交换,以该值作为分界点,左右两边继续重复上述过程(递归),直到左边>=右边。程序代码如下(第一个函数是完成一次的分裂):

void split(int a[], int first, int last, int &pos)
{
int left = first;
int right = last;
while (left < right)
{
while (a[first] < a[right])
{
right--;
}
while (a[first] > a[left])
{
left--;
}
if (left < right)
{
int temp = a[right];
a[right] = a[left];
a[left] = temp;
}
}
pos = right;
int temp2 = a[right];
a[right] = a[first];
a[first] = temp2;
}
void sort4(int a[],int first,int last)
{
int pos = 0;
if (first<last)
{
split(a, first, last, pos);
sort4(a, first, pos - 1);
sort4(a, pos+1, last);
}
}


快速排序是不稳定排序,比如 5 3 4 3 6 7 8 9,第一次5和后面的那个3交换位置。

- 归并排序

将要排序的数组递归拆分,最终拆分为只剩一个或无记录,然后将两个有序的数组排列起来。程序如下:

void Merge(int a[], int p, int q, int r)
{
int n1 = q - p + 1;
int n2 = r - q;
int* a1 = new int[n1];
int* a2 = new int[n2];
for (int i = 0; i < n1;i++)
a1[i] = a[p+i];
for (int j = 0; j < n2; j++)
a2[j] = a[j + q + 1];
int i=0, j=0, k=p;
while (i<n1&&j<n2)
{
if (a1[i] <= a2[j])
a[k++] = a1[i++];
else
a[k++] = a2[j++];
}
while (i < n1)
a[k++] = a1[i++];
while (j < n2)
a[k++] = a2[j++];
delete[] a1;
delete[] a2;
}
void sort5(int a[], int p,int r)
{
if (p<r)
{
int q = (p + r) / 2;
sort5(a, p, q);
sort5(a, q + 1, r);
Merge(a, p, q, r);
}
}


归并排序是稳定排序。

- 堆排序

堆排序就是将数组看成一个完全二叉树,然后先从底到上转换成堆,将第一个数和最后一个数交换,然后剩下的数再转换为堆。代码如下:

void heapify(int a[], int initial, int n)
{
int left = 2 * initial+1;
int right = left + 1;
int pos = initial;
if (left<n&&a[left]>a[initial])
pos = left;
if (right<n&&a[right]>a[pos])
pos = right;
if (pos!=initial)
{
int temp = a[initial];
a[initial] = a[pos];
a[pos] = temp;
heapify(a, pos, n);
}
}
void sort6(int a[], int n)
{
for (int i = n / 2 - 1; i >= 0;i--)
{
heapify(a, i, n);
}
for (int i = n - 1; i > 0;i--)
{
int temp = a[0];
a[0] = a[i];
a[i] = temp;
heapify(a, 0, i);
}
}


堆排序是不稳定的,它要从低向上进行交换。

- 希尔排序

希尔排序是分组插入排序,将整个数组以一定增量分成若干子序列,分别进行直接插入排序,然后将增量减小,再进行排序,最后整个序列中的元素基本有序的,再进行一次直接插入排序,因为直接插入排序在元素基本有序的情况下效率很高,所以希尔排序在时间效率上有较大提高。

void sort7(int a[], int n)
{
for (int gap = n / 2; gap > 0;gap=gap/2)
{
for (int j = gap; j < n;j++)
{
if (a[j]<a[j-gap])
{
int temp = a[j];
int k = j - gap;
while (k>=0&&a[k]>temp)
{
a[k+gap] = a[k];
k = k - gap;
}
a[k+gap] = temp;
}
}
}
}


希尔排序也是不稳定的,因为要经过几次不同的插入排序,在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,最后其稳定性就会被打乱。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: