https://www.cnblogs.com/chengxiao/p/6129630.html
a.将无需序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
复杂度O(nlogk)
#include
using namespace std;
void print(int arr[],int len){
for(int i=0;i<len;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
void swap(int arr[],int i,int j){
int temp=arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void adjustHeap(int arr[],int i,int len){
int temp=arr[i]; //先取出当前元素i
for(int k=2*i+1;k<len;k=2*k+1){
//从i结点的左子结点开始,也就是2i+1处开始
if(k+1<len && arr[k]<arr[k+1]){
//如果左子结点小于右子结点,k指向右子结点
k++;
}
if(arr[k]>temp){
//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
arr[i] = arr[k];
i=k;
}else{
break;
}
}
arr[i] = temp; //将temp值放到最终的位置
}
void sort(int arr[],int len){
//1.构建大顶堆
for(int i=len/2-1;i>=0;i--){
//由下至上从最后一个非叶子节点开始创建堆
adjustHeap(arr,i,len);
print(arr,len);
}
//2.调整堆结构+交换堆顶元素与末尾元素
for(int j=len-1;j>=0;j--){
swap(arr,0,j); //将堆顶元素与末尾元素进行交换
adjustHeap(arr,0,j); //重新对堆进行调整
print(arr,len);
}
}
int main(){
int arr[10] = {
9,8,7,6,5,4,3,2,1,0};
int len = sizeof(arr)/sizeof(arr[0]);
sort(arr,len);
return 0;
}
复杂度为O(nlogn)
逆序最坏复杂度变成了O(n^2)
不稳定,是冒泡排序的跳跃
分治核心,归并排序也是分治核心
package com.nrsc.sort;
public class QuickSort {
public static void main(String[] args) {
int[] arr = {
49, 38, 65, 97, 23, 22, 76, 1, 5, 8, 2, 0, -1, 22 };
quickSort(arr, 0, arr.length - 1);
System.out.println("排序后:");
for (int i : arr) {
System.out.println(i);
}
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
// 找寻基准数据的正确索引
int index = getIndex(arr, low, high);
// 进行迭代对index之前和之后的数组进行相同的操作使整个数组变成有序
quickSort(arr, 0, index - 1);
quickSort(arr, index + 1, high);
}
}
private static int getIndex(int[] arr, int low, int high) {
// 基准数据
int tmp = arr[low];
while (low < high) {
// 当队尾的元素大于等于基准数据时,向前挪动high指针
while (low < high && arr[high] >= tmp) {
high--;
}
// 如果队尾元素小于tmp了,需要将其赋值给low
arr[low] = arr[high];
// 当队首元素小于等于tmp时,向前挪动low指针
while (low < high && arr[low] <= tmp) {
low++;
}
// 当队首元素大于tmp时,需要将其赋值给high
arr[high] = arr[low];
}
// 跳出循环时low和high相等,此时的low或high就是tmp的正确索引位置
// 由原理部分可以很清楚的知道low位置的值并不是tmp,所以需要将tmp赋值给arr[low]
arr[low] = tmp;
return low; // 返回tmp的正确位置
}
}
稳定
时间复杂度 O(nlogn)
#include
#include
using namespace std;
void print(int arr[],int len){
for(int i=0;i<len;i++){
cout<<arr[i]<<" ";
}
cout<<endl;
}
void merge(int arr[],int l,int mid,int r){
int *help = new int(r-l+1);
int p=l,q=mid+1;
int i=0;
while(p<=mid && q<=r){
help[i++] = arr[p]<arr[q]?arr[p++]:arr[q++];
}
while(p<=mid) help[i++] = arr[p++];
while(q<=r) help[i++] = arr[q++];
for(int j=0;j<r-l+1;j++){
arr[l+j] = help[j];
}
}
void MergeSort(int arr[],int l,int r){
if(l<r){
int mid = (l+r)/2;
MergeSort(arr,l,mid);
MergeSort(arr,mid+1,r);
merge(arr,l,mid,r);
}
}
int main(){
int arr[10] = {
9,8,7,6,5,4,3,2,1,0};
int len = sizeof(arr)/sizeof(arr[0]);
MergeSort(arr,0,len-1);
print(arr,len);
return 0;
}