**
插入排序、希尔排序、冒泡排序、快速排序、选择排序、堆排序
**
在这里#include<iostream>
#include<assert.h>
using namespace std;
void InsertSort(int *arr,int sz)//插入排序
{
for (int i = 0; i < sz-1; i++)
{
int end = i;
int key = arr[end + 1];
while (end >= 0)
{
if (arr[end] > key)
{
arr[end + 1] = arr[end];
--end;
}
else
break;
}
arr[++end] = key;
}
}
void ShellSort(int *arr,int s)//希尔排序
{
int gap = s;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < s - gap ;i++)
{
int end = i;
int key = arr[end+gap];
while (end>0)
{
if (arr[end] > key)
{
arr[end + gap] = arr[end];
end = end - gap;
}
else
break;
}
arr[end+gap] = key;
}
}
}
void Swap(int &a, int &b)
{
if (a > b)
{
int temp = a;
a = b;
b = temp;
}
}
void Bubble(int *arr, int sz)//假冒泡排序
{
for (int i = 0; i < sz - 1; i++)
{
for (int j = i + 1; j < sz ; j++)
{
if (arr[i]>arr[j])
Swap(arr[i], arr[j]);
}
}
}
void Bubble1(int *arr, int sz)//冒泡排序
{
for (int i = 0; i < sz - 1; ++i)
{
for (int j = 0; j < sz-1-i; ++j)//为什么是sz-1-i呢,当内层循环到sz-1是,arr[j]是倒数第二个数,arr[j+1]是最后一个数,
{
if(arr[j]>arr[j+1])
Swap(arr[j],arr[j+1]);
}
}
}
void Bubble2(int *arr, int sz)//添加标志位的冒泡排序,可以减少没必要的比较
{
/*mark的作用arr2[]数组可以体现出来,当外层循环一次后,排序已经完毕。如若按Bubble1的算法,只有当内外层的所有循环跑完后,程序才会终止。而Bubble2中的mark,外层进行第二次循环时,内层循环没有调换过次序,mark标志会一直是0,当外层循环进入第三次循环时,由于mark=0,循环条件不成立,所以整个循环就终止了。从而大量减少了不必要的循环比较。*/
int mark = 1;
for (int i = 0; i < sz - 1&&mark; ++i)
{
mark = 0;
for (int j = 0; j < sz - 1 - i; ++j)
{
if (arr[j]>arr[j + 1])
{
Swap(arr[j], arr[j + 1]);
mark = 1;
}
}
}
}
void QuickSort(int *arr,int left,int right)//快速排序,左右指针法
{
int key = right;
int begin = left;
int end = right;
while (left >= right)
{
return;
}
while (left < right)
{
while (left < right&&arr[left] <= arr[key])
left++;
while (left < right&&arr[right] >= arr[key])
right--;
if (left < right&&arr[left] != arr[right])
{
Swap(arr[left], arr[right]);
}
}
Swap(arr[left],arr[key]);
QuickSort(arr, begin, left - 1);//递归对当前key值左侧数组进行排序,right=key=key前一个数值,begin=key左侧最左边的值。
QuickSort(arr,left+1,end);//递归对当前key值右侧的数组进行排序,begin=当前key值后一个位置上的数值,key=right=右侧最右边的值
}
void QuickSort1(int *arr, int left, int right)//快速排序,挖坑法
{
while (left >= right)
return;
int hollow = right;
int begin = left;
int end = right;
int key = arr[right];
while (left < right)
{
while (left < right&&arr[left] <= key)
left++;
arr[hollow] = arr[left];
hollow = left;
while (left < right&&arr[right] >= key)
right--;
arr[hollow] = arr[right];
hollow = right;
}
if (left == right)
{
arr[left] = key;
}
QuickSort1(arr, begin, left - 1);
QuickSort1(arr, left + 1, end);
}
/*
void QuickSort2(int *arr, int left, int right)//挖坑法改进,代码有问题
{
while (left >= right)
return;
int hollow = right;
int begin = left;
int end = right;
int key = arr[right];
while (left < right)
{
while (left < right&&arr[left] < key)
left++;
Swap(arr[hollow], arr[left]);
hollow = left;
while (left<right&&arr[right]>key)
right--;
Swap(arr[hollow], arr[right]);
hollow = right;
}
QuickSort2(arr, begin, left - 1);
QuickSort2(arr, left + 1, end);
}
*/
void SelectSort(int *arr, int sz)//选择排序
{
int i, j, min;
for (i = 0; i < sz; ++i)
{
min = i;
for (j = i + 1; j < sz; ++j)
/*i=0第一次循环,把i=0右边剩余的元素一一和第一个元素对比,比第一个小的,把其下表赋给min,在继续向后找,如果有更小的,更新min。次时已经找出整个数组中最小的值。然后,i=1从第二次循环,把i=1右边剩余的元素一一和第二个元素对比,比第二个小的,把其下表赋给min,在继续向后找,如果有更小的,更新min。次时已经找出整个数组中最小的值。以此类推。。。。*/
{
if (arr[j] < arr[min])
min = j;
}
//if (min != i)//词条语句多余,内层循环循环完之后,自然就找出除已经排好序元素之外的最小元素。
Swap(arr[i], arr[min]);
}
}
void AdjustDown(int *arr,int father,int sz)//堆的建立(默认为大堆)
{
int child = father * 2 + 1;
while (child < sz)
{
if (child + 1 < sz&&arr[child + 1] > arr[child])//确保孩子节点中较大的与父节点交换
{
child++;
}
if (arr[child]>arr[father])
{
Swap(arr[child], arr[father]);
father = child;
child = father * 2 + 1;
}
else
return;
}
}
void AdjustUp(int *arr, int father, int sz)//堆的建立(小堆)
{
int child = father * 2 + 1;
while (child < sz)
{
if (child + 1 < sz&&arr[child] > arr[child + 1])
child++;
if (arr[child] < arr[father])
{
swap(arr[child], arr[father]);
father = child;
child = father * 2 + 1;
}
else
return;
}
}
void HeapSort(int *arr, int sz)//堆排序
{
int i = 0;
for (i = (sz - 2) / 2; i >= 0; i--)
{
AdjustDown(arr, i, sz);//建立堆,大堆
}
while (sz > 1)
{
sz--;
swap(arr[0], arr[sz]);//首元素和最后一个元素交换,最大元素就被排在最后,对剩余的元素堆化。重复此过程
AdjustDown(arr, 0, sz);
}
}
void HeapSort1(int *arr, int sz)//堆排序,
{
int i = 0;
for (i = (sz - 2) / 2; i >= 0; i--)
{
AdjustUp(arr, i, sz);//建立堆,小堆
}
while (sz > 1)
{
sz--;
swap(arr[0], arr[sz]);//首元素和最后一个元素交换,最小元素就排在最后,对剩余的元素堆化。重复此过程。
AdjustUp(arr, 0, sz);
}
}
void Merge(int *arr, int *temp, int begin1, int end1, int begin2, int end2)//合并数组
{
int pos = begin1;//pos用来记录原始数组当前所在的位置
int index = begin1;//index用来记录新开辟数组到当前所在的位置
while (begin1 <= end1&&begin2 <= end2)//比较两个有序区间值的大小,对有序区间进行合并
{
if (arr[begin1] < arr[begin2])
temp[index++] = arr[begin1++];
else
temp[index++] = arr[begin2++];
}
while (begin1 <= end1)//对部分有序区间进行合并
{
temp[index++] = arr[begin1++];
}
while (begin2 <= end2)
{
temp[index++] = arr[begin2++];
}
memcpy(arr + pos, temp + pos, sizeof(int)*(end2 - pos + 1));//从temp+pos所指的内存地址的起始位置开始,拷贝(end2-pos+1)个字节的数据到目标arr+pos所指的内存地址的起始位置中
}
void _Merge(int *arr,int *temp,int left,int right)//分裂数组
{
if (left >= right)
return;
int mid = left + (right - left) / 2;
_Merge(arr,temp,left,mid);//分裂数组
_Merge(arr, temp, mid+1, right);//分裂数组
Merge(arr,temp,left,mid,mid+1,right);//合并数组
}
void MerageSort(int *arr, int sz)//归并排序
{
int *tmp = new int[sz];
_Merge(arr, tmp, 0, sz - 1);
delete []tmp;
}
void Print(int *arr, int sz)
{
for (int i = 0; i < sz; i++)
cout << arr[i] << ' ';
cout << endl;
}
int main()
{
int arr[] = { 5, 7, 6, 4, 9, 2, 8, 1, 3};
int arr1[] = { 10, 90, 40, 54, 63, 78, 11, 52, 45, 65, 79 };
int arr2[] = {9,1,2,3,4,5,6,7,8};
int arr3[] = {9,8,7,6,5,4,3,2,1,0};
int arr4[] = {90, 10, 50, 80, 30, 70, 40, 60, 20};
int arr_4[] = { 90, 10, 50, 80, 30, 70, 40, 60, 20 };
int arr5[] = {10,30,50,20,90,60,80,70,40};
//cout << "冒泡排序:";
//int sz = sizeof(arr) / sizeof(arr[0]);
//InsertSort(arr, sz);//插入排序
//Print(arr, sz);
//Bubble2(arr2, sz);//冒泡排序
//Print(arr2, sz);
cout << "希儿排序:";
int sz1 = sizeof(arr1) / sizeof(arr1[0]);
ShellSort(arr1, sz1);//希尔排序
Print(arr1, sz1);
cout << "快速排序:";
int sz = sizeof(arr) / sizeof(arr[0]);
QuickSort(arr, 0,sz-1);//快速排序
Print(arr, sz);
cout << "选择排序:";
int sz3 = sizeof(arr3) / sizeof(arr3[0]);
SelectSort(arr3, sz3);
Print(arr3, sz3);
cout << "堆排序:";
int sz4 = sizeof(arr4) / sizeof(arr4[0]);
HeapSort(arr4, sz4);//用大堆,升序排序
Print(arr4,sz4);
cout << "(小)堆排序:";
int sz_4 = sizeof(arr_4) / sizeof(arr_4[0]);
HeapSort1(arr_4, sz_4);//利用小堆,降序排序
Print(arr_4, sz_4);
cout << "归并排序:";
int sz5 = sizeof(arr5) / sizeof(arr5[0]);
MerageSort(arr5, sz5);
Print(arr5,sz5);
system("pause");
return 0;
}插入代码片