您的位置:首页 > 其它

各种排序算法分析与比较

2017-03-26 21:35 239 查看
1.直接插入排序

每一趟将一个待排序的元素作为关键字,按照其关键字的大小插入到已经排好的部分序列的适当位置上。平均时间复杂度为O(n2),空间复杂度为O(1)。

void InsertSort(int R[], int n)
{
if (R == nullptr || n<=0)
return;
int i, j;
int temp;
for (i = 1; i < n; ++i)
{
j = i - 1;
temp = R[i];
while (j >= 0 && R[j] > temp)
{
R[j+1] = R[j];
--j;
}
R[j+1] = temp;
}
}


2.冒泡排序

平均时间复杂度为O(n2),空间复杂度为O(1)

void BubbleSort(int R[], int n)
{
if (R == nullptr || n <= 0)
return;
int i, j;
int temp;
int flag = 0;
for (i = n; i >= 1; --i)
{
flag = 0;//每次重新置为0
for (j = 1; j < i; ++j)
{
if (R[j - 1] > R[j])
{
temp = R[j];
R[j] = R[j - 1];
R[j - 1] = temp;
flag = 1;//有数据交换,flag=1;
}
}

if (flag == 0)
return;
}
}

3.快速排序

快速排序以枢轴为中心,将序列分成两部分。关键是枢轴的划分。

时间复杂度:最好的情况下为O(nlogn),最坏为O(n2)

空间复杂度:O(log2n)

递归算法:

void QuickSort(int R[], int low, int high)
{
if (low >= high)
return;
int pivot = Partition(R, low, high);
QuickSort(R, low, pivot - 1);
QuickSort(R, pivot + 1, high);
}
几种划分算法:

1.从后往前扫描直到小于枢轴的位置j,将R[j]交换到i的位置;从i开始往后扫描,直到遇到大于枢轴的位置i,把R[i]交换到j的位置。

int Partition(int R[], int low, int high)
{
int pivot = R[low];
while (low < high)
{
while (low < high && R[high] >= pivot)
--high;
if (low < high)
R[low] = R[high];
while (low < high && R[low] <= pivot)
++low;
if (low < high)
R[high] = R[low];
}
R[low] = pivot;
return low;
}
2.从前往后扫描,遇到小于枢轴的值,则递增small值,如果当前下标与small不相等,则交换,保证small左边的元素都小于枢轴。

int Partition(int data[], int start, int end)
{
int index= RandomInRange(start,end);//随机生成一个数作为中枢值
swap(data[index],data[end]);//最后一个值作为中枢值

int small=start-1;
for(index=start; index<end; ++index)
{
if(data[index]<data[end])
{
++small;
if(small != index)
swap(data[index], data[small]);
}
}
++small;
swap(data[small], data[end]);
return small;
}

3.两边同时进行扫描,并交换位置。

int Partition3(int R[], int low, int high)
{
int pivot = R[low];
int i = low + 1;
int j = high;
while (i <= j)
{
while (i <= j && R[j] >= pivot)
--j;
while (i <= j && R[i] <= pivot)
++i;
if (i < j)
{
swap(R[i], R[j]);
++i;
--j;
}
}
swap(R[low], R[j]);
return j;
}

4.堆排序

堆是一种数据结构,可以把堆看成完全二叉树,这棵完全二叉树满足:任何一个非叶节点的值都不大于(或不小于)其左右孩子节点的值。若父节点大于孩子节点,则叫大顶堆,父节点小于孩子节点,则叫小顶堆。

堆排序的主要操作是将序列调整为堆。

时间复杂度:O(n log2n);空间复杂度:O(1)

void Shift(int R[], int low, int high)
{
int i = low;
int j = 2 * i + 1;
int temp = R[i];
while (j <= high)
{
if (j < high && R[j] < R[j + 1])
{
++j;
}
if (temp < R[j])
{
R[i] = R[j];
i = j;
j = 2 * i + 1;
}
else
break;
}
R[i] = temp;
}
void HeapSort(int R[], int n)
{
int i;
int temp;
for (i = n / 2 - 1; i >= 0; --i)
{
Shift(R, i,n);
}
for (i = n-1; i >= 1; --i)
{
temp = R[0];
R[0] = R[i];
R[i] = temp;
Shift(R, 0, i - 1);
}
}

4.二路归并排序

归并排序的时间复杂度和初始序列无关,平均情况下为O(n log2n),最好情况下为O(nlog2n),最坏情况下也为O(nlog2n)。

空间复杂度:因归并排序需要转存整个待排序列,因此空间复杂度为O(n)

void Merge(int R[], int tempArray[], int low, int mid, int high)
{
int i = low;
int j = mid + 1;
int k = i;
while (i <= mid && j <= high)
{
if (R[i] < R[j])
tempArray[k++] = R[i++];
else
tempArray[k++] = R[j++];
}
while (i <= mid)
tempArray[k++] = R[i++];
while (j <= high)
tempArray[k++] = R[j++];
for (int i = low; i <= high; ++i)
{
R[i] = tempArray[i];
}
}
void MergeSort(int R[],int tempArray[], int low, int high)
{
if (low < high)
{
int mid = (low + high) / 2;
MergeSort(R, tempArray, low, mid);
MergeSort(R, tempArray, mid + 1, high);
Merge(R, tempArray, low, mid, high);
}
}
void MergeSort(int R[], int n)
{
int *tempArray = new int
;
MergeSort(R, tempArray, 0, n - 1);
delete []tempArray;
}
5.计算排序

适用于元素的取值范围比较小的情况。

1>统计每个元素的个数

2>统计每个元素比自身小的元素个数

template <typename Type>
void CountingSort(Type array[], int low, int high, int range)//range为元素的取值范围
{
Type *result = new Type[high - low + 1];
Type *valueCount = new Type[range + 1];

for (int i = 0; i <= range; ++i)
{
valueCount[i] = 0;
}

for (int i = low; i <= high; ++i)
{
valueCount[array[i]] += 1;
}

for (int i = 1; i <= range; ++i)
{
valueCount[i] += valueCount[i - 1];
}

for (int i = high; i >= low; --i)
{//form high to low , in order to guarantee the stable sort
result[valueCount[array[i]] - 1] = array[i];
--valueCount[array[i]];
}

int i = low;
while (i <= high)
{
array[i] = result[i - low];
++i;
}

delete[] result;
delete[] valueCount;
}

参考博客:

http://blog.csdn.net/anonymalias/article/details/11547039

http://www.cnblogs.com/wxisme/p/5243631.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: