排序模板

C++排序模板

快速排序

#include<iostream>
using namespace std;

int Partition(int a[],int low,int high)
{
	int i=low;
	int j=high;
	int pivot = a[low];
	while(i<j)
	{
		while(i<j && a[j]>=pivot)
		{
			j--;		
		}
		a[i] = a[j];
		while(i<j && a[i]<=pivot)
		{
			i++;
		} 
		a[j] = a[i];
	}
	a[i] = pivot;
	return i;
}

void quickSort(int a[],int low,int high)
{
	if(low<high)
	{
		int index =  Partition(a,low,high); //第一趟快速排序,划分左右
		quickSort(a,low,index-1);
		quickSort(a,index+1,high);
	}
} 


void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++)
        cout << arr[i] << " ";
    //cout << endl;
}

// 主函数来测试上述代码
int main() {
	int n;
	cin>>n;
	int a[n];
 	for (int i = 0; i < n; i++)
 	{
 		cin>>a[i];
	}
	//对a数组进行排序 
	quickSort(a,0,n-1);
 	for (int i = n-1; i>=0; i--)
 	{
 		cout<<a[i]<<" ";
	}
    return 0;
}

归并排序

#include <iostream>
using namespace std;

int a[5005],temp[5005];

void merge(int a[],int mid,int low,int high)
{
	int i=low,j=mid+1,k=low;
	while(i<=mid && j<=high)
	{
		if(a[i]<a[j])
		{
			temp[k] = a[i];
			k++;
			i++;
		}
		else{
			temp[k] = a[j];	
			k++;
			j++;
		}
	}
	while(i<=mid)
	{
		temp[k] = a[i];
		k++;
		i++;
	}
	while(j<=high)
	{
		temp[k] = a[j];
		k++;
		j++;
	}
	for(int p=low;p<=high;p++)
	{
		a[p] = temp[p];	
	}	
}

void mergeSort(int a[],int low,int high)
{
	if(low>=high)
		return;
	 
	int mid = (low+high)/2;
	mergeSort(a,low,mid);
	mergeSort(a,mid+1,high); //上面是为了分解 
	merge(a,mid,low,high);  //这一步是为了归并 
} 

// 主函数来测试上述代码
int main() {
	int n;
	cin>>n;
	
 	for (int i = 0; i < n; i++)
 	{
 		cin>>a[i];
	}
	//对a数组进行排序 
	mergeSort(a,0,n-1);
 	for (int i = n-1; i>=0; i--)
 	{
 		cout<<a[i]<<" ";
	}
    return 0;
}

冒泡排序

Bubble Sort(冒泡排序)是一种简单直观的排序算法。

它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。

遍历数列的工作是重复地进行,直到没有再需要交换,也就是说该数列已经排序完成。

冒泡排序,排序n轮,每一轮遍历一遍数组。当发现两个连续数字顺序不对时,交换他们。

如果是正序排列,每一次 swap,减少一个逆序对(所以,冒泡排序,进行了几次 swap,就可以判断数列中有多少个逆序对)

#include <iostream>
using namespace std;

void bubbleSort(int a[],int n)
{
	for(int i=0;i<n;i++)
	{
		bool flag = true;
		for(int j=0;j<n-1-i;j++)
		{
			if(a[j]>a[j+1])
			{
				int t=a[j];
				a[j] = a[j+1];
				a[j+1] = t;
				flag = false;
			}
		}
		if(flag)
			break;	
	} 	
}

// 主函数来测试上述代码
int main() {
	int n;
	cin>>n;
	int a[n];
 	for (int i = 0; i < n; i++)
 	{
 		cin>>a[i];
	}
	//对a数组进行排序 
	bubbleSort(a,n);
 	for (int i = n-1; i>=0; i--)
 	{
 		cout<<a[i]<<" ";
	}
    return 0;
}

选择排序

首先在未排序序列中找到最小(最大)元素,存放到排序序列的起始位置

再从剩余未排序元素中继续寻找最小(最大)元素,然后放到已排序序列的末尾

重复第二步,直到所有元素均排序完毕

为什么不稳定呢?(此处一定要会举例证明)

例如:

5 3 5 2 4

第一趟排序,第 1 个 5 和 2 发生交换

2 3 5 5 4

但是,这样两个 5 的先后顺序发生了改变。所以,不稳定。

#include <iostream>
using namespace std;

void selectSort(int a[],int n)
{
	for(int i=0;i<n;i++)
	{
		int min_index  = i;
		for(int j=i;j<n;j++)
		{
			if(a[j] < a[min_index])
			{
				min_index = j;
			}
		}
		swap(a[min_index],a[i]);	 
	}
}

// 主函数来测试上述代码
int main() {
	int n;
	cin>>n;
	int a[n];
 	for (int i = 0; i < n; i++)
 	{
 		cin>>a[i];
	}
	//对a数组进行排序 
	selectSort(a,n);
 	for (int i = n-1; i>=0; i--)
 	{
 		cout<<a[i]<<" ";
	}
    return 0;
}

插入排序

将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。

从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。

如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面【所以稳定】。

插入排序,插在哪个位置,其实是一个遍历的过程,这个遍历是就近遍历,遍历到合适的位置,就会停下来。

如果是一个已经排好序的序列,更改了某一个值,想要快速的得到新的序列,那么可以对变更的值,进行向左找位置,向右找位置,O(n)O(n)的时间或者更小,完成新的排序(《插入排序》)

posted @ 2024-08-04 14:06  梁君牧  阅读(21)  评论(0编辑  收藏  举报