排序、搜索

堆排序

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;
}

你可能感兴趣的:(coding)