时间复杂度:就是指函数计算执行的操作次数。
二分查找法的时间复杂度:O(logn/2)=O(lgn)
递归的时间复杂度:递归的总次数*每次递归次数
空间复杂度:对象的个数
递归的时间复杂度:递归深度O(N)
一、快速排序
(1)最好的情况:取决于key值的大小,如果每次划分后对一个元素定位,该元素的左侧子序列与右侧子序列的长度相同,则下一步就是对两个长度减半的子序列进行排序。
时间复杂度On(logn)
(2)最坏情况:待排序的元素序列已经按其排序码从小到大排好序的情况下,其递归树为单支树,每次划分只得到一个比上次少一个元素的子序列,这样,必须经过n-1趟才能把所有元素定位,而且第1趟需要经过n-1次个比较才能找到第一个元素的安放位置,
第2趟需要经过n-2次个比较才能找到第2个元素的安放位置,时间复杂度为:
O(n^2);
(3)空间复杂度
由于快排是递归的,需要有一个栈存放每层递归调用时的指针和参数,最大递归调用层次数与递归树深度一致,O(lg(N))
#pragma
once
#include
<iostream>
#include
"assert.h"
using
namespace
std;
//快速排序
int
Partsort(
int
*
a
,
int
left
,
int
right
)
//升序
{
assert
(
a
);
//判空
int
key=
right
;
int
begin=
left
;
int
end=
right
-1;
while
(begin<end)
{
while
(
a
[begin]<=
a
[key] && begin < end)
{
begin++;
}
while
(
a
[end]>=
a
[key] && begin <end)
{
end--;
}
if
(begin< end)
{
swap(
a
[begin],
a
[end]);
}
}
if
(
a
[end]>
a
[key])
{
swap(
a
[end],
a
[key]);
}
return
end;
}
void
Quicksort(
int
*
a
,
int
left
,
int
right
)
{
if
(
left
<
right
)
{
int
mid=Partsort(
a
,
left
,
right
);
Quicksort(
a
,
left
,mid-1);
Quicksort(
a
,mid+1,
right
);
}
}
//经过优化的快排
int
PartsortNew(
int
*
a
,
int
left
,
int
right
)
{
int
key=
right
;
int
prev=
left
-1;
int
cur=
left
;
while
(cur<
right
)
{
if
(
a
[cur]<
a
[key] && ++prev!=cur)
{
swap(
a
[cur],
a
[prev]);
}
cur++;
}
swap(
a
[++prev],
a
[key]);
//找到最终排好序的a[right]位置,左边比a[right]小,右边比a[right]大
return
prev;
}
void
QuicksortNew(
int
*
a
,
int
left
,
int
right
)
{
if
(
left
<
right
)
{
int
mid=PartsortNew(
a
,
left
,
right
);
QuicksortNew(
a
,
left
,mid-1);
QuicksortNew(
a
,mid+1,
right
);
}
}
void
Print_Array(
int
*
a
,
int
len
)
{
for
(
int
i=0;i<
len
;i++)
{
cout<<
a
[i]<<
" "
;
}
cout<<endl;
}
#include
"sort.h"
void
QuicksortTest()
{
int
a[]={2,9,5,7,4,1,0,6,8,3};
Print_Array(a,
sizeof
(a)/
sizeof
(a[0]));
int
len=
sizeof
(a)/
sizeof
(a[0]);
Quicksort(a,0,len-1);
Print_Array(a,len);
}
void
QuicksortNewTest()
{
/*int a[]={2,9,5,7,4,1,0,6,8,3};*/
int
a[]={0,1,2,3,4,5,6,7,8,9};
Print_Array(a,
sizeof
(a)/
sizeof
(a[0]));
int
len=
sizeof
(a)/
sizeof
(a[0]);
QuicksortNew(a,0,len-1);
Print_Array(a,len);
}
int
main()
{
/*QuicksortTest();*/
QuicksortNewTest();
system(
"pause"
);
return
0;
}
二、选择排序
时间复杂度 :O(n^2)
空间复杂度:O(1)
计算:
(n-1)+(n-2)+(n-3)+...1=1/2n(n-1)=n^2
最好的情况:???
最坏的情况:逆序排列
void
ChoiceSort(
int
*
a
,
int
len
)
//选择排序
{
for
(
int
i=0;i<
len
;i++)
{
for
(
int
j=i+1;j<
len
;j++)
{
if
(
a
[i]>
a
[j])
{
swap(
a
[i],
a
[j]);
}
}
}
}
三、冒泡排序
时间复杂度:O(n^2)
计算:
(n-1)+(n-2)+(n-3)+...1=1/2n(n-1)=n^2
空间复杂度:O(1)
最好的情况:有序
最坏的请况:逆序排列
void
BubbleSort(
int
*
a
,
int
len
)
//冒泡排序
{
for
(
int
i=0;i<
len
;i++)
{
for
(
int
j=0;j<
len
-i-1;j++)
{
if
(
a
[j]>
a
[j+1])
{
swap(
a
[j],
a
[j+1]);
}
}
}
}
void
BubbleSortNew(
int
*
a
,
int
len
)
//改进后的冒泡排序
{
bool
exchange;
for
(
int
i=0;i<
len
;i++)
{
exchange=
true
;
for
(
int
j=0;j<
len
-i-1;j++)
{
if
(
a
[j]>
a
[j+1])
{
swap(
a
[j],
a
[j+1]);
exchange=
false
;
}
}
if
(exchange==
true
)
{
return
;
}
}
}
四、插入排序
时间复杂度:O(n)
最好情况:有序 O(n)
最坏情况:逆序 O(n^2)
计算:
1+2+3+..(n-1)
空间复杂度 O(1)
void
InsertSort(
int
*
a
,
int
len
)
{
for
(
int
i=0;i<
len
-1;i++)
{
int
index=i;
int
end=
a
[index+1];
while
(index>=0 && end<
a
[index])
{
a
[index+1]=
a
[index];
index--;
}
a
[++index]=end;
}
}
五、希尔排序
时间复杂度:O(n^1.3)
最好情况:有序 O(n)
最坏情况:逆序 O(n^2)
计算:
1+2+3+..(n-1)
空间复杂度 O(1)
void
ShellSort(
int
*
a
,
int
len
)
//希尔排序 类似于插入排序
{
assert
(
a
);
int
gap=
len
;
while
(gap>1)
{
gap=gap/3+1;
for
(
int
i=0;i<
len
-gap;i++)
{
int
index=i;
int
end=
a
[index+gap];
while
(
a
[index]>end && index>=0)
{
a
[index+gap]=
a
[index];
index-=gap;
}
a
[index+gap]=end;
}
}
}
六、堆排序
时间复杂度:O(nlogn)
最好的情况:有序 O(nlogn)
最坏情况:逆序 O(nlogn)
空间复杂度:、、
void
AdjustDown(
int
*
a
,
int
parent
,
int
len
)
{
int
child=
parent
*2+1;
while
(child<
len
)
{
if
((child+1)<
len
&&
a
[child]<
a
[child+1])
{
child++;
}
if
(
a
[child]>
a
[
parent
])
{
swap(
a
[child],
a
[
parent
]);
parent
=child;
child=
parent
*2+1;
}
else
{
break
;
}
}
}
void
HeapSort(
int
*
a
,
int
len
)
{
for
(
int
i=(
len
-2)/2;i>=0;i--)
//构建堆,只能保证根节点的值是最大的
{
AdjustDown(
a
,i,
len
);
}
for
(
int
i=0;i<
len
;i++)
{
swap(
a
[0],
a
[
len
-1-i]);
AdjustDown(
a
,0,
len
-i-1);
}
}
七、归并排序
void
Merge(
int
* src,
int
* dst,
int
begin1,
int
end1,
int
begin2,
int
end2)
{
assert(src&&dst);
size_t index = begin1;
while
(begin1 < end1 && begin2 < end2)
{
if
(src[begin1] < src[begin2])
{
dst[index++] = src[begin1++];
}
else
{
dst[index++] = src[begin2++];
}
}
if
(begin1 < end1)
{
while
(begin1 < end1)
{
dst[index++] = src[begin1++];
}
}
else
{
while
(begin2 < end2)
{
dst[index++] = src[begin2++];
}
}
}
void
_MergeSort(
int
* src,
int
* dst,
int
left,
int
right)
{
if
(left < right-1)
{
/*if (right - left < 13)
{
InsertSort();
}
else
{
}*/
//int mid = left + (right-left)>>1;
int
mid = left + (right-left)/2;
cout<<left<<
","
<<mid<<
","
<<right<<endl;
_MergeSort(src, dst, left, mid);
_MergeSort(src, dst, mid, right);
// [left,mid) [mid, right)
Merge(src, dst, left, mid, mid, right);
memcpy(src+left, dst+left, (right-left)*
sizeof
(
int
));
}
}
void
MergeSort(
int
* a, size_t size)
{
assert(a);
int
* tmp =
new
int
[size];
_MergeSort(a, tmp, 0, size);
delete
[] tmp;
}
八、基数排序
九、计数排序