#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void InsertSort(int a[],int n);
void InsertSort1(int a[],int n);
void sheelSort(int a[],int n);
void BubbleSort(int a[],int n);
void quickSort(int a[],int low,int high);
void selectSort(int a[],int n);
void heapSort(int a[],int len);
void mergeSort(int a[],int low,int high);
void merge(int a[],int low,int mid,int high);
void insertHeap(int a[],int len,int x);
void heapDelete(int a[],int len,int pos);
void buildMaxHeap(int a[],int len);
int c[10];
int main(){
int a[11]={15,6,5,4,1,2,3,1,64,153};
int b[12]={0,6,5,4,1,2,3,1,64,153,1};
buildMaxHeap(b,10);
insertHeap(b,10,999);
heapDelete(b,11,1);
return 0;
}
/*插入排序,升序 o(n^2)*/
void InsertSort(int a[],int n){
int i,j,temp;
for (i = 1; i < n; ++i) {
if (a[i]<a[i-1]){//如果a[i]>a[i-1]的话就不用排序了
temp = a[i];
for (j = i-1; j >= 0 && a[j]>temp; --j) {//当a[j]<=temp的时候就不用再比较了,减少了一波排序
a[j+1]=a[j];
}
a[j+1]=temp;/*此时a[j+1]的位置空出来了*/
}
}
}
/*插入排序,通过折半查找来优化 o(n^2)*/
void InsertSort1(int a[],int n){
int i,temp;
int low,high,mid;
for (i = 1; i < n; ++i) {
if (a[i]<a[i-1]){//如果a[i]>a[i-1]的话就不用排序了
temp = a[i];
high=i-1;
low=0;
while (high>=low){
mid = (high+low)/2;
if (a[mid]>temp) high=mid-1;
else low=mid+1;
}
for (int k = i-1; k >= low; --k) {/*所有下标大于low的元素,他们都必定大于temp,因此,全部后移一位*/
a[k+1]=a[k];
}
a[low]=temp;
}
}
}
//希尔排序 无法计算时间复杂度
void sheelSort(int a[],int n){
int d,i,j;
for (d = n/2; d >= 1; d=d/2) {
/*下面是插入排序*/
for (i = d+1; i <= n ; ++i) {/*i++使得每次处理一个不同的子表*/
if (a[i]<a[i-d]){
a[0]=a[i];//a[0]是暂存单元,不是哨兵
for (j = i-d; j>0 && a[0]<a[j] ; j-=d) {/*对选中的子表进行插入排序*/
a[j+d]=a[j];
}
a[j+d]=a[0];
}
}
}
}
//交换函数
void swap(int *a,int *b){
int temp = *a;
*a = *b;
*b= temp;
}
void BubbleSort(int a[],int n){
for (int i = 0; i < n-1; ++i) {
bool flag=false; //表示本趟是否发生交换的标志
for (int j = n-1; j > i ; --j) {//从后往前冒泡,可以确保最小的那个元素位于数组第一位
if (a[j-1] > a[j]){//这个条件保证了这个算法是稳定的
swap(&a[j-1],&a[j]);
flag = true;
}
}
if (flag == false)
return;
}
}
/*快速排序*/
int partition(int a[],int low,int high){
int pivot=a[low];//pivot为基准
while (low<high){//用low和high确定基准的最终位置,最终会使得low==high时推出循环
while (low<high && a[high]>=pivot) --high;/*使得所有大于pivot的元素到达high的右边*/
a[low]=a[high];/*把小于pivot的元素送到low的左边*/
while (low<high && a[low]<=pivot) ++low;
a[high]=a[low];
}
a[low]=pivot;
return low;
}
void quickSort(int a[],int low,int high){
if (low <high){
int pivotPosition=partition(a,low,high);
quickSort(a,low,pivotPosition-1);
quickSort(a,pivotPosition+1,high);
}
}
//选择排序
void selectSort(int a[],int n){
for (int i = 0; i < n-1; ++i) {//最后一个不用进行选择排序
int min=i;
for (int j = i+1; j < n; ++j) {
if (a[i]>a[j]) min=j;
}
if (min!=i) swap(&a[min], &a[i]);/*加上一个判断可以减少一次交换*/
}
}
/*堆排序*/
//将以k为根的子树调整为大根堆
void headAdjust(int a[],int k,int len){
a[0]=a[k];
for (int i = 2*k; i <=len; i*=2) {//i=2*k找到子结点,i <=len是否到达了叶子结点,i*=2实现下坠操作
if(i<len && a[i]<a[i+1]){/*i<len是防止没有右孩子的情况*/
i++;//取key较大的子结点下标
}
if (a[0]>=a[i]) break;//筛选结束
else{
a[k]=a[i];
k=i;/*修改k值,以便继续向下筛选*/
}
}
a[k] = a[0];
}
//建立大根堆
void buildMaxHeap(int a[],int len){
for (int k = len/2; k >0 ; --k) {
headAdjust(a,k,len);
}
}
void heapSort(int a[],int len){
buildMaxHeap(a,len);
for (int i = len; i > 1; --i) {
swap(&a[i],&a[1]);
headAdjust(a,1,i-1);
}
}
//堆的插入
void insertHeap(int a[],int len,int x){
a[len+1]=x;
for (int i = len+1; i > 1 ; i=i/2) {//上升操作
if (a[i]>a[i/2]) swap(&a[i], &a[i / 2]);
else break;
}
}
//删除堆中某个结点
void heapDelete(int a[],int len,int pos){
swap(&a[pos], &a[len + 1]);
len--;
for (int i = pos*2; i <= len; i*=2) {
if (i<len && a[i]<a[i+1])
i++;
if (a[i]<a[pos])
break;
else{
swap(&a[i], &a[pos]);
pos=i;
}
}
}
/*归并排序,单个这样的函数只能合并两个有序数组*/
void merge(int a[],int low,int mid,int high){
int i,j,k;
for (k = low; k <= high; ++k) {
c[k]=a[k];
}
for (i=low,j=mid+1,k=i; i<=mid && j<=high; ++k) {//i=low,j=mid+1,k=i三个指针,i<=mid && j<=high只要有一方被排完了,那么就退出循环,++k不管结果如何,此次k++
if (c[i]<=c[j])
a[k]=c[i++];
else
a[k]=c[j++];
}
while (i<=mid) a[k++]=c[i++];/*把剩下还没有比较的元素放进去*/
while (j<=high) a[k++]=c[j++];
}
/*化整为零,当每一个数组最多只有两个元素的时候,他们的子数组必定是有序的,那么就符合了merge函数的条件*/
void mergeSort(int a[],int low,int high){
if (low<high){//当a里面只有一个元素的时候就必定不满足这个条件,只有一个元素,便不再需要排序了
int mid=(low+high)/2;
mergeSort(a,low,mid);
mergeSort(a,mid+1,high);
merge(a,low,mid,high);
}
}