#include <stdio.h>
#include <malloc.h>
void swap2(int a, int b);
void swap(int* data, int m, int n);
void printArray(int* data, int n);

void bubble1(int* data, int n);//冒泡排序1
void bubble2(int* data, int n);//冒泡排序2
void bubble3(int* data, int n);//冒泡排序3
void bubble4(int* data, int n);//冒泡排序4

void insertSort1(int* data, int n);//插入排序
void insertSort2(int* data, int n);

void binaryInsertSort(int* data, int n);//折半插入排序

void qs(int* data, int n);//快速排序
void quickSort(int* data, int low,int high);/**/
int adjust(int* data,int low, int high);
int adjust2(int* data,int low, int high);


// void merge_sort(int* data, int n);
void QuickSort(int* data, int n);//快速排序
void Qsort(int* data,int lo,int hi);
int Partition(int *data,int lo,int hi) ;

void NonRecursionQucickSort(int* data, int n);//非递归快速排序
void norecursionQuickSort(int* data, int low, int high);

void sortPartOrdered(int* data, int low, int mid, int high);
void merge(int* data, int low, int high);
void mergesort(int* data, int n);//归并排序
void norecursionMerge_sort(int *list, int length);//非递归归并排序

// void shellSort(int* data, int n)//希尔排序

#define N 10
int data[] ={3,1,6,8,2,4,7,9,0,5};
int main(int argc, char const *argv[])
{
bubble1(data,N);
printArray(data,N);

bubble2(data,N);
printArray(data,N);

bubble3(data,N);
printArray(data,N);

bubble4(data,N);
printArray(data,N);

insertSort1(data,N);
printArray(data,N);

insertSort2(data,N);
printArray(data,N);

binaryInsertSort(data,N);
printArray(data,N);

qs(data,N);
printArray(data,N);

QuickSort(data,N);
printArray(data,N);

NonRecursionQucickSort(data,N);
printArray(data,N);

mergesort(data,N);
printArray(data,N);

norecursionMerge_sort(data,N);
printArray(data,N);

return 0;

}
void swap2(int a, int b)
{
a=a+b;
b=a-b;
a=a-b;
}
void printArray(int* data, int n)
{
static int num = 0;
++num;
printf("%2d ", num);
for (int i = 0; i < n; ++i)
{
printf("%d\t",data[i]);
}
}
void swap(int* data, int m, int n)
{
data[m] ^= data[n];
data[n] ^= data[m];
data[m] ^= data[n];
}

void bubble1(int* data,int n)
{
int count = 0;
for (int i = 0; i < n-1; ++i)
{
for(int j=0;j<n-1-i;j++)
{
if(data[j]>data[j+1])
{
swap(data,j,j+1);
count++;
}
}
}
}
void bubble2(int* data, int n)
{
int flag = 1;
int k = n-1;
while(flag)
{

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

void bubble3(int* data, int n)
{
int k ;
int flag = n-1;//無序: 0--flag
while(flag)
{
k = flag;
flag = 0;
for(int j=0;j<k;j++)
{
if(data[j]>data[j+1])
{
swap(data,j,j+1);
flag = j+1;
}
}
}
}

void bubble4(int* data, int n)
{
int k = n-1;
int flag =n-1;
while(flag)
{
k = flag;
flag = 0;
for (int i = 0; i < k; ++i)
{
if(data[i]>data[i+1])
{
swap(data,i,i+1);
flag = i+1;
}
}
}
}

void insertSort1(int* data, int n)
{
int temp;
int j;
for(int i=1;i<n;i++)
{
if(data[i]<data[i-1])
{
temp = data[i];
for(j=i-1;j>=0 && data[j]>temp;--j)
{
data[j+1] = data[j];
}
data[j+1] = temp;
}
}
}

void insertSort2(int* data, int n)
{
int temp;
int j;
for (int i = 1; i < n; ++i)
{
if(data[i]<data[i-1])
{
temp = data[i];
for(j=i-1;data[j]>temp;--j);
data[j+1] = temp;
}
}
}

int locate(int* data, int i)
{
/* int j=i-1;
while(data[j]>data[i])
--j;
return j+1;*/ //直接插入

int low = 0;
int high = i-1;
int mid;
while(low<=high)
{
mid = (low+high)/2;
if(data[mid]==data[i]) return mid+1;
else if(data[mid]<data[i]) low =mid+1;
else high = mid-1;
}
return low;
}
void binaryInsertSort(int* data, int n)
{
int i,j,temp;
int location;
for (i = 1; i < n; ++i)
{
if(data[i]<data[i-1])
{
temp = data[i];
location = locate(data,i);
for(j=i-1;j>=location;--j)
{
data[j+1] = data[j];
}
data[location] = temp;
}
}
}

/*void shellSort(int* data, int n)
{


}
*/
void qs(int* data, int n)
{
quickSort(data,0,n-1);
}
void quickSort(int* data, int low,int high)
{
int location;
if(low<high)
{
location = adjust2(data,low,high);
// location = adjust(data,low,high);
quickSort(data,low,location-1);
quickSort(data,location+1,high);
}
}

int adjust(int* data,int low, int high)
{
int temp = data[low];
while(low<high)
{
while(low<high && data[high]>=temp) --high;
if(low<high)
{
data[low] = data[high];
++low;
}
while(low<high && data[low]<=temp) ++low;
if(low<high)
{
data[high] = data[low];
--high;
}
}
data[low] = temp;
return low;
}


int adjust2(int* data, int l, int h)
{
int temp = data[l];
int low = l;
int high = h;
while(low<high)
{
while(low<high && data[high]>=temp) --high;
while(low<high && data[low]<=temp) ++low;
if(low<high)
{
swap2(data[low],data[high]);
}
}
data[l] = data[low];
data[low] = temp;
return low;
}

void QuickSort(int* data, int n)
{
Qsort(data,0,n-1);
}
void Qsort(int* data,int lo,int hi)
{
int k;
if(lo<hi)
{
k=Partition(data,lo,hi);
Qsort(data,lo,k-1);
Qsort(data,k+1,hi);

}
}


int Partition(int *data,int lo,int hi)
{
int key=data[lo];
int l=lo-1;
int h=hi+1;
int temp;
for(;;)
{
do{
h--;
}while(data[h]>key);

do{
l++;
}while(data[l]<key);

if(l<h)
{
temp=data[h];
data[h]=data[l];
data[l]=temp;
}
else
{
return h;
//各位注意了,这里的返回值是h。不是返回各位习以为常的枢纽元素,即不是l之类的。
}
}
}

void NonRecursionQucickSort(int* data, int n)
{
norecursionQuickSort(data,0,n-1);
}
void norecursionQuickSort(int* data, int low, int high)
{
if(low>=high) return;
int S[high];
int p=-1;
int l,h;
int index;
S[++p] = low;
S[++p] = high;

while(p>=0)
{
h = S[p--];
l = S[p--];
index = Partition(data,l,h);
if(l<index-1)
{
S[++p] = l;
S[++p] = index-1;
}
if(index+1<h)
{
S[++p] = index+1;
S[++p] = h;
}
}
}

void mergesort(int* data, int n)
{
merge(data,0,n-1);
}
void merge(int* data, int low, int high)
{
if(low==high) return;
int mid = (low+high)/2;
merge(data,low,mid);
merge(data,mid+1,high);
sortPartOrdered(data, low, mid,high);
}

void sortPartOrdered(int* data, int low, int mid, int high)
{
if(data[mid]<=data[mid+1]) return;
int* temp = (int*)malloc( (high+1)*sizeof(int) );
int i = low;
int j = mid+1;
int index = -1;
while(i<=mid && j<=high)
{


if(data[i]<data[j]) temp[++index] = data[i++];
else temp[++index] = data[j++];
}

while(i<=mid)
{
temp[++index] = data[i++];
}
while(j<=high)
{
temp[++index] = data[j++];
}
for(int k=low;k<=high;k++)
{
data[k] = temp[k-low];
}
}


void norecursionMerge_sort(int *list, int length){ //非递归
int i, left_min, left_max, right_min, right_max, next;
int *tmp = (int*)malloc(sizeof(int) * length);
if (tmp == NULL){
fputs("Error: out of memory\n", stderr);
abort();
}
for (i = 1; i < length; i *= 2)
for (left_min = 0; left_min < length - i; left_min = right_max){
right_min = left_max = left_min + i;
right_max = left_max + i;
if (right_max > length)
right_max = length;
next = 0;
while (left_min < left_max && right_min < right_max)
tmp[next++] = list[left_min] > list[right_min] ? list[right_min++] : list[left_min++];
while (left_min < left_max)
list[--right_min] = list[--left_max];
while (next > 0)
list[--right_min] = tmp[--next];