您的位置:首页 > 其它

排序算法二冒泡排序和快排

2017-08-02 01:49 435 查看
冒泡排序想必大家都非常熟悉了,这里就直接贴代码了

void BubbleSort(int array[],int len)
{
assert(array && len>0 );

for(int i = 0; i < len-1; ++i)
{
int flag = 1;
for(int j = 0; j < len-1-i; ++j)
{
if(array[j] > array[j+1])
{
swap(array[j], array[j+1]);
flag = 0;
}
}

if(flag == 1)
break;
}
}


时间复杂度为O(N*N),最好的情况下:优化后正序有序为O(n),稳定的算法。

没有优化的与原始序列的状态无关,优化后与原始序列的状态有关

快排

挖坑法

双指针法

//paration版本一:挖坑法
int Paration(int array[], int left, int right)
{
int key = array[right];

while(left < right)
{
while((left < right)&&(array[left] <= key) )
{
left++;
}
swap(array[left], array[right]);

while((left < right) && (array[right] >= key))
{
right--;
}
swap(array[left], array[right]);
}
return left;
}

//paration版本二:双指针法
int Paration2(int array[], int left, int right)
{

int key = array[right];
int pcur = left;
int pre = pcur-1;

while(pcur <= right)
{
if((array[pcur] <= key) && (++pre != pcur) )
{
swap(array[pcur], array[pre]);
}
++pcur;
}
return pre;
}

void QuickSort(int array[], int left ,int right)
{
assert(array);

if(left < right)
{
int index = Paration2(array, left ,right);
QuickSort(array, left, index-1);
QuickSort(array, index+1, right);
}
}


非递归实现:

void QuickSort2(int array[], int left, int right)
{
stack<int> s;

s.push(right);
s.push(left);

while(!s.empty())
{
int left = s.top();
s.pop();
int right = s.top();
s.pop();

if(left < right) //防止下面插入index+1, inex-1越界。
{
int mid = (left+right)/2;
int index = Paration2(array, left, right);

s.push(right);
s.push(index+1);

s.push(index-1);
s.push(left);
}
}
}


优化:

1)三数取中法

2)当区间已经划分到很小的时候可以改用插入排序

3)尾递归减少递归次数

//三数取中法,防止取到极端数据
int Middle(int array[], int left, int mid, int right)
{
if(array[left] > array[right])
{
if(array[right] > array[mid])
return right;
else if(array[left] > array[mid])
return mid;
else
return left;
}
else
{
if(array[right] < array[mid])
return right;
else if(array[left] < array[mid])
return mid;
else
return left;
}
}

//paration版本二:双指针法
int Paration2(int array[], int left, int right)
{

int mid = (left+right)/2;
int pos = Middle(array, left, mid, right);
swap(array[pos], array[right]);

int key = array[right];
int pcur = left;
int pre = pcur-1;

while(pcur <= right)
{
if((array[pcur] <= key) && (++pre != pcur) )
{
swap(array[pcur], array[pre]);
}
++pcur;
}
return pre;
}

void InsertSort(int array[], int size)
{
for(int i = 1; i < size; ++i)
{
int temp = array[i];
int end = i-1;

while(end>=0 && array[end] > temp)
{
array[end+1] = array[end];
end--;
}
array[end+1] = temp;
}
}

void QuickSort(int array[], int left ,int right)
{
assert(array);

while(right-left > 5)  //使用尾部递归
{
int index = Paration2(array, left ,right);
QuickSort(array, left, index-1);
left = index+1;
}

if(right-left <= 5)  //当分成很小的区间时,插入排序效率更高。
{
InsertSort(array+left, right-left+1);
}
}


时间复杂度为O(n*lgn),最好情况为O(n*lgn),最坏情况O(n*n),因为递归空间复杂度O(lgn)

不稳定的算法

最坏的情况下:基本有序时,退化为冒泡排序,几乎要比较N*N次,故为O(N*N)

它的应用场景是大规模的数据排序

快速排序算法的实际执行性能依赖与切分是否均衡,当正好把数组从中间”切开”时,

快速排序的实际性能最好。

切分越不均衡快速排序的实际性能就越差,

最坏情况下(第一次选取的切分元素是数组里最小的,第二次的切分元素是第二小的…)

算法的时间复杂度会退化到O(n^2)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息