1.归并排序
1.找到这个待排序数组的中点
2.两个子排序 left到mid mid+1到right
3.然后就是merge过程,需要重新开辟一个新的数组去 helparray
4.时间复杂度O*(N*LogN)
void merge(vector<int> s, int L, int M, int R) {
int helparray[R - L + 1];
int p1 = L; //双指针向右遍历
int p2 = M + 1;
int i = 0;
while (p1 <= M && p2 <= R) {
if (s[p1] <= s[p2]) //将子序列赋值到新开辟的数组
{
helparray[i++] = s[p1++];
} else {
helparray[i++] = s[p2++];
}
//处理两个子序列剩下的元素
while (p1 <= M) {
helparray[i++] = s[p1++];
}
while (p2 <= R) {
helparray[i++] = s[p2++];
}
//将help排序过的元素返回原数组
for (int j = 0; j < sizeof(s) / sizeof(int); ++j) {
s[L + i] = helparray[i];
}
};
}
void process(vector<int> s, int L, int R) {
//左右边界判断
if (L == R) {
return;
}
int mid = L + ((R - L) >> 1);//找到中点位置
process(s, L, mid);//子排序分割
process(s, mid + 1, R);//子排序分割
merge(s, L, mid, R); //归并过程
}
2.快速排序
1.每次整行递归处理,每轮排序都会有一个数在最终的位置
2.[i]<num 与小于区域的后一个位置交换 小于区右扩i++
3.[i]=num 原地不动 i++
4.[i]>num 与大于区域的前一个位置交换,大于区左扩 i不变 // leetcode 荷兰国旗问题可以用这个解决
void swap(vector<int> s,int i,int j)
{
if(i!=j)
{
int eor=s[i]^s[j];
s[i]=eor^s[i];
s[j]=eor^s[j];
}
}
//对区域进行划分
void partition(vec &s, int L, int R) {
//定义两个区的边界两个指针
arr[0] = L - 1;
arr[1] = R;//大于区的左边界//10
while (L < arr[1])//当i指针与右边界相撞 循环结束
{
if (s[L] < s[R]) {//
swap(s, ++arr[0], L++);//S[R]作为标准值 所有值和他比较
} else if (s[L] == s[R]) {
L++;
} else if (s[L] > s[R]) {
swap(s, L, --arr[1]);
}
}
swap(s, arr[1], R);
//将基准元素与大于区域的第一位置交换//返回第一个元素代表当前基准值pivot的第一个相同数字下标,第二个代表最后一个相同数字下标
}
void quickSort(vec &s, int L, int R) {
if (L < R) {
int x = (rand() % (R - L + 1));
swap(s, x, R); //将随机产生的基准值与最后一个位置的元素进行交换 产生在A-B范围内的随机数只需要rand()%x
partition(s, L, R);//返回两个元素数组 第一个元素代表当前基准值pivot的第一个相同数字下标,第二个代表最后一个相同数字下标
quickSort(s, L, arr[0] - 1);//处理小于区
quickSort(s, arr[1] + 1, R);//处理小于区
}
}
3.桶排序
1:我们要进行堆的构造,将一个数组中的元素按照层次遍历的顺序插入到二叉树中
2:规定一个heapsize来定义堆的大小,如果出堆一个元素就heapsize减一 逻辑意义上的从空间删除
3:定义两个方法 一个heapInsert堆插一个heapify堆化
void heapInsert(vector<int> &vc,int index) //插入节点
{
//二叉树的知识 父亲结点:(i-1)/2 左孩子:2*i 右孩子:2*i+1
while(vc[index]>vc[(index-1)/2])
{
swap(vc,index,(index-1)/2);
index=(index-1)/2;
}
}
void heapify(vector<int> &vc, int index, int heapsize) //这个方法可以将一个数组变成一个大根堆
{
int left = 2 * index + 1;//右孩子
//判断是否还有孩子
while (left < heapsize) {
//得出两个孩子的大小比较
int max = left;
if ((left + 1 < heapsize) && (vc[left] < vc[left + 1])) //右孩子在范围内
{
max = left + 1;
}
max = vc[max] > vc[index] ? max : index;
if (max == index) {
break;
}
swap(vc, max, index);
index = max;//对一层树操作
}
}
void heapsort(vector<int> &vc)//将一个数组先变成大根堆,在将他输出
{
if (vc.size()<2)
{
return;
}
for (int i = 0; i <vc.size() ; ++i) //大根堆的形成
{
heapInsert(vc,i);
}
cout<<"大根堆的形成"<<endl;
for (int i = 0; i < vc.size(); ++i)
{
cout<<vc[i]<<endl;//输出元素
}
int heapsize=vc.size();
swap(vc,0, heapsize-1);//弹出顶端元素
while (heapsize>0)
{
heapify(vc,0,heapsize);
swap(vc,0,--heapsize);
}
}