排序算法
冒泡排序法二分查找法快速排序
1. 冒泡排序法
冒泡排序只需两层循环,外层循环控制冒泡的趟数,内层循环控制冒泡的方式,即用相邻两个元素进行比较,不满足则进行交换直至区间末尾。冒泡排序法外循环:冒泡的总趟数 N-1,每冒泡一次只能将一个元素排好,最后一趟只剩一个元素无需再冒泡,因此总的冒泡趟数为N-1.冒泡排序法内循环:用相邻进行比较,不满足则进行交换。需要N-1次比较。此时这种冒泡排序的时间复杂度为O(N^2)。特殊情况:若遇到某趟排序若已有序,那么就不再需要冒泡,就像下面这种情况。那么设置flag标签flag=1,若它在此趟冒泡中有交换,则flag被置为0。此趟冒泡结束后检测flag,flag未被改变则说明此趟排序已经有序,直接break跳出循环,不再进行冒泡。时间复杂度O(N^2)空间复杂度O(1)稳定性:稳定(没有间隔区间进行交换,所以稳定)
void BubbleSort(int arr
[], int n
)
{
for(int i
=0; i
<n
-1; ++i
)
{
int flag
= 1;
for(int j
=0; j
<n
-i
-1; ++j
)
{
if(arr
[j
] > arr
[j
+1])
{
int tmp
= arr
[j
];
arr
[j
] = arr
[j
+1];
arr
[j
+1] = tmp
;
flag
= 0;
}
}
if(1 == flag
)
{
berak
;
}
}
}
2. 二分查找法
二分查找的前提条件是有序数列,普通查找则不需要。查找到返回该元素的下标,否则返回-1。普通查找的时间复杂度为O(N),二分查找的时间复杂度为O(log(N))N/2/2···/2=1,2^m=N(m为折半查找的次数),那么m=log2(N),二分查找的时间复杂度就为O(log2(N))。
int Find(int arr
[], int n
, int key
)
{
for(int i
=0; i
<n
; ++i
)
{
if(arr
[i
] == key
)
return i
;
}
return -1;
}
int BinarySearch1(int arr
[], int size
, int key
)
{
int low
= 0;
int high
= size
-1;
int mid
;
while(low
<= high
)
{
mid
= low
+(high
-low
)>>1;
if(key
< arr
[mid
])
high
= mid
-1;
else if(key
> arr
[mid
])
low
= mid
+1;
else
return mid
;
}
return -1;
}
BinarySearch1注意以下5个点:
low=0; high=size-1; // [ ] 闭区间,high为最后一个元素的下标 low <= high; mid= low+(high-low)>>1; high=mid-1; low=mid+1;
其示意图如下图所示:
int BinarySearch2(int arr
[], int size
, int key
)
{
int low
= 0;
int high
= size
;
int mid
;
while(low
< high
)
{
mid
= low
+(high
-low
)>>1;
if(key
< arr
[mid
])
high
= mid
;
else if(key
> arr
[mid
])
low
= mid
+1;
else
return mid
;
}
return -1;
}
BinarySearch2注意以下5个点:
low=0; high=size; // [ ) 左闭右开,high为最后一个元素的下一个位置 low < high; mid= low+(high-low)>>1; high=mid; low=mid+1;
其示意图如下图所示:
3. 快速排序
快速排序的框架(递归)
void QuickSort(int array
[],int left
,int right
)
{
if(righ
-left
>1)
{
int div
=partion(array
,left
,right
);
QuickSort(array
,left
,div
);
QuickSort(array
,div
+1,right
);
}
}
三种数据分割方法 1.hoare法
int partion(int array
[],int left
,int right
)
{
int begin
=left
;
int end
=right
-1;
int key
=array
[right
-1];
}
2.挖坑法 3.前后指针法