整理各类排序算法以及二分查找如下:
//直接插入排序
//时间复杂度:O(n^2);空间复杂度:O(1);稳定;
//越有序查找速度越快:O(n)
void Insert_sort(int *arr,int len)
{
int i;
int j;
int tmp;
for(i = 1 ; i < len ; ++i)
{
tmp = arr[i];
for(j = i - 1 ; j >=0 ; --j)
{
if(arr[j] > tmp)
{
arr[j+1] = arr[j];
}
else
{
arr[j+1] = tmp;
break;
}
}
arr[j+1] = tmp;
}
}
//希尔排序
,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本
//分组+直接插入
//时间复杂度:O(n^1.3~1.5);空间复杂度:O(1);不稳定;
void Shell(int *arr,int len,int gap)
{
int tmp;
for(int i = gap ; i < len ; ++i)
{
tmp = arr[i];
int j;
for(j = i - gap ; j >=0 ; j -= gap)
{
if(arr[j] > tmp)
{
arr[j + gap] = arr[j];
}
else
break;
}
arr[j + gap] = tmp;
}
}
void Shell_sort(int *arr,int len)
{
int d[] = {5,3,1};
for(int i = 0 ; i < sizeof(d)/sizeof(d[0]) ; ++i)
{
Shell(arr,len,d[i]);
}
}
//冒泡排序
//时间复杂度:O(n^2);空间复杂度:O(1);稳定;
void Bubble_sort(int *arr,int len)
{
for(int i = 0 ; i < len - 1 ; ++i)
{
for(int j = 0 ; j < len - i - 1 ; ++j)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
//快速排序
,平均性能最快,有序时效率最低,退化为选择排序时间复杂度:O(n^2)
//一次快排后,基准左侧小于基准,右侧大于基准,可用来分离奇偶数
//时间复杂度:O(n*log);空间复杂度:O(log);不稳定;
int Quick_part(int *arr,int low,int high)
{
int tmp = arr[low];
while(low < high)
{
while(low < high && arr[high] >= tmp)
high--;
arr[low] = arr[high];
while(low < high && arr[low] <= tmp)
low++;
arr[high] = arr[low];
}
arr[low] = tmp;
return low;
}
void Quick(int *arr,int low,int high)
{
int par = Quick_part(arr,low,high);
if(low < par - 1)
Quick(arr,low,par-1);
if(high > par + 1)
Quick(arr,par+1,high);
}
void Quick_sort(int *arr,int len)
{
Quick(arr,0,len-1);
}
//直接选择排序
//每一趟从待排序的记录中选出关键字最小的记录,顺序放在已排好序的子文件的最后
//时间复杂度:O(n^2);空间复杂度:O(1);不稳定;
void Select_sort(int *arr,int len)
{
int tmp;
int minindex;
for(int i = 0 ; i < len ; ++i)
{
minindex = i;
for(int j = i + 1 ; j < len ; ++j)
{
if(arr[minindex] > arr[j])
minindex = j;
}
tmp = arr[i];
arr[i] = arr[minindex];
arr[minindex] = tmp;
}
}
//堆排序
:树形选择排序
//处于最大堆的根节点的元素一定是这个堆中的最大值
//每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素重新调整为最大堆
//时间复杂度:O(n*log);空间复杂度:O(1);不稳定;
//最好情况下,时间复杂度为O(1).
void HeapAdjust(int *arr,int start,int end)//时间复杂度:O(log);空间复杂度:O(1)
{
int tmp = arr[start];//根节点的值
int parent = start;
for(int i = 2*start+1 ; i <= end ; i = 2*i+1)//下一跳至左孩子
{
if(i+1 <= end && arr[i] < arr[i+1])//若有右孩子,跳至左右孩子中较大值处
i++;
if(arr[i] > tmp)
{
arr[parent] = arr[i];//若子节点数值大于父节点,将值赋给父节点
parent = i;//父节点向下移动
}
else
break;
}
arr[parent] = tmp;
}
void Heap_sort(int *arr,int len)
{
for(int i = (len - 2)/2 ; i >= 0 ; --i)
HeapAdjust(arr,i,len-1);//第一次建立大根堆,从最后一颗子树开始,从后往前调整
//此时根节点最大
int tmp;
for(int i = 0 ; i < len - 1 ; ++i)
{
tmp = arr[0];
arr[0] = arr[len-1-i];
arr[len-1-i] = tmp;
HeapAdjust(arr,0,len-i-2);//自上到下调整
}
}
//归并排序
:归并是指将若干个已排序的子文件合并成一个有序的文件
//时间复杂度:O(n*log);空间复杂度:O(n);稳定;
void Merge(int *arr,int len,int gap)//时间复杂度:O(n*log)
{
int low1 = 0;//第一个归并段的起始下标
int high1 = low1+gap-1;//第一个归并段的结尾下标
int low2 = high1+1;//第二个归并段的起始下标
int high2 = low2+gap<len?low2+gap-1:len-1;//第二个归并段的结尾下标
int *brr = (int *)malloc(len*sizeof(int));
int i = 0;//brr下标
//归并段成对
while(low2 < len)
{
//两个归并段都还有数据
while(low1<=high1 && low2<=high2)
{
if(arr[low1] <= arr[low2])
{
brr[i++] = arr[low1++];
}
else
{
brr[i++] = arr[low2++];
}
}
//一个归并段已完成另一个还有数据
while(low1 <= high1)
{
brr[i++] = arr[low1++];
}
while(low2 <= high2)
{
brr[i++] = arr[low2++];
}
low1 = high2+1;
high1 = low1+gap-1;
low2 = high1+1;
high2 = low2+gap<len?low2+gap-1:len-1;
}
//不成对的归并段
while(low1 < len)
{
brr[i++] = arr[low1++];
}
for(i = 0 ; i < len ; i++)
{
arr[i] = brr[i];
}
free(brr);
}
void Merge_sort(int *arr,int len)
{
for(int i = 1 ; i < len ; i *= 2)
{
Merge(arr,len,i);
}
}
void Show(int *arr,int len)
{
for(int i = 0 ; i < len ; ++i)
{
cout<<arr[i]<<" ";
}
cout<<endl;
}
//二分查找 有序方可
int Search(int *arr,int len,int key)
{
if(arr == NULL || len <= 0)
return -1;
int left = 0;
int right = len - 1;
int mid;
while(left <= right)
{
mid = (right - left) / 2 + left;
if(arr[mid] == key)
{
return mid;
}
else if(arr[mid] < key)
{
left = mid +1;
}
else
{
right = mid - 1;
}
}
return -1;
}
以上代码均运行无误:
int main()
{
int arr[] = {24,10,45,8,5,17,29,2,57};
int len = sizeof(arr)/sizeof(arr[0]);
//Insert_sort(arr,len);
//Shell_sort(arr,len);
//Bubble_sort(arr,len);
//Quick_sort(arr,len);
//Select_sort(arr,len);
//Heap_sort(arr,len);
Merge_sort(arr,len);
Show(arr,len);
cout<<Search(arr,len,57);
return 0;
}