关于排序

1. 归并排序

①、排序思路

归并排序的基础思想是将数列划分成单一元素。

int mid=0;
if (l<r) {
	mid= (l+r)/2;
//从中间分割
	MSort (arr,arrTmp,l,mid);
	MSort (arr,arrTmp,mid+1,r);
}

再在和并时两两比较。

while (LS <= LE && RS <= RE)
//谁小就先加入,大的后加入
	if (arr[LS] <= arr[RS])
		arrTmp[index++] = arr[LS++];
	else
		arrTmp[index++] = arr[RS++];
//左边或右边还剩下元素(前面保证有一个放好的数列),就把剩下的元素依次放入备用数组
	while (LS <= LE) arrTmp[index++] = arr[LS++];
	while (RS <= RE) arrTmp[index++] = arr[RS++];

放入原数列中。

for (int i=0; i<arrLen; i++, RE--)
	arr[RE] = arrTmp[RE];

②、完整代码

#include <iostream>
using namespace std;
void Merge(int*,int*,int,int,int);
void MSort(int*,int*,int,int);
int main() {
    int n;
    cin>>n;
	int a[n],b[n];
	for(int i=0;i<n;i++)
		cin>>a[i];
	MSort(a, b, 0, n-1);
	for(int i=0;i<n;i++)
		cout<<a[i]<<" ";
	return 0;

}
void Merge (int arr[], int arrTmp[], int LS, int RS, int RE) {
//LS是左部分起始下标
//RE是右部分结束下标
//LE与RS类似
	int arrLen = RE - LS + 1;
	int LE = RS - 1;
	int index = LS;
	while (LS <= LE && RS <= RE)

	//谁小就先加入,大的后加入
		if (arr[LS] <= arr[RS])
			arrTmp[index++] = arr[LS++];
		else
			arrTmp[index++] = arr[RS++];
	

//左边或右边还剩下元素(前面保证有一个放好的数列),就把剩下的元素依次放入备用数组
	while (LS <= LE) arrTmp[index++] = arr[LS++];

	while (RS <= RE) arrTmp[index++] = arr[RS++];

//复制到原数组
	for (int i=0; i<arrLen; i++, RE--)
		arr[RE] = arrTmp[RE];
}

void MSort (int arr[],int arrTmp[],int l,int r) {
	int mid=0;
	if (l<r) {
		mid= (l+r)/2;

	//从中间分割
		MSort (arr,arrTmp,l,mid);
		MSort (arr,arrTmp,mid+1,r);

	//合并两数组
		Merge (arr,arrTmp,l,mid+1,r);
	}
}

③、思路延伸

题目描述:
给定1,2,…,n的一个排列,求它的逆序数。
内存限制:128 MiB
时间限制:1000 ms
输入格式:
第一行是一个整数n,表示该排列有n个数(n <= 300000)。 第二行是n个不同的正整数,之间以空格隔开,表示该排列。
输出格式:
输出该排列的逆序数
题目分析:
在进行组合的时候:

while (LS <= LE && RS <= RE)
	if (arr[LS] <= arr[RS])
		arrTmp[index++] = arr[LS++];
	else
		✧arrTmp[index++] = arr[RS++];while (LS <= LE) arrTmp[index++] = arr[LS++];
	while (RS <= RE) arrTmp[index++] = arr[RS++];

被✧ ✧标记的该行可以解读成:若该处有逆序对,则将对中小的那个数放入备用数组中。我们就借此来统计逆序对数。
参考代码:

#include <iostream>
using namespace std;
int ans;
void Mesort (int arr[],int tmp[],int ls,int le,int re) {
   int rs=le+1,index=ls,al=re-ls+1;
   while (ls<=le && rs<=re) {
   	if (arr[ls]<=arr[rs]) tmp[index++]=arr[ls++];
   	else tmp[index++]=arr[rs++],ans+=le-ls+1;
   }
   while (ls<=le) tmp[index++]=arr[ls++];
   while (rs<=re) tmp[index++]=arr[rs++];
   for (long long i=0;i<al;i++,re--) arr[re]=tmp[re]; 
}
void Msort (int arr[],int tmp[],int l,int r) {
   if (l<r) {
   	int mid= (l+r)/2;
   	Msort (arr,tmp,l,mid);
   	Msort (arr,tmp,mid+1,r);
   	Mesort (arr,tmp,l,mid,r);
   }
}

int main () {
   int n;
   cin>>n;
   int arr[n],tmp[n];
   for (int i=0;i<n;i++)
   	cin>>arr[i];
   Msort(arr,tmp,0,n-1);
   cout<<ans;
   return 0;
}

2. 希尔排序

①、排序思路

希尔排序的基本思想是将几组数据进行插入排序,其中,内层两层循环与插入排序相差无几,只是将几个位置同时插入排序。
https://blog.csdn.net/weixin_49692699/article/details/107645400
可以去我的另一篇博客详细了解插入排序

②、完整代码

#include <iostream>
using namespace std;
void ShellSort(int*,int);
int main() {

//输入数组长度及数组各项
	int n;
	cin>>n;
	int arr[n];
	for(int i=0;i<n;i++)
		cin>>arr[i];

//升序排列
	ShellSort(arr,n);
	for(int i=0;i<n;i++)
		cout<<arr[i]<<' ';

//输出排序好的数组
	return 0;
}
void ShellSort(int arr[], int len) {

//开始排序
    int tmp;
    int i,j,k;
    for(i=len>>1;i>0;i=i>>1)
        for(j=i;j<len;j++) {
            tmp=arr[j];

            for(k=j-i;k>= 0 && arr[k]>tmp;k-=i)
                arr[k+i] = arr[k];
            arr[k+i]=tmp;
        }
}

3. 桶排序

①、排序思路

桶排序局限于正整数的排序,并且局限性很大。又称计数排序。他只是依靠数组的下标来达成排序的效果,但在其他地方更加实用,如去重,过滤等。

②、完整代码

#include <iostream>
using namespace std;
int main() {

//输入数组长度及数组各项
	int n;
	cin>>n;
	int arr[20000]={0},tmp;
	for(int i=0;i<n;i++) {
		cin>>tmp;
		arr[tmp]++;
	}
	for(int i=0;i<20000;i++)
		if(arr[i]!=0)
		    for(int j=0;j<arr[i];j++)
		        cout<<i<<" ";

//输出“排序”好的数组
	return 0;
}

4. 基数排序

①、排序思路

基数排序的基本思想是将不同数位上的数字桶排,这样做的好处是:空间只需要10个桶。
PS:我这里用的是队列,也可以用数组、链表等数据结构,了解队列可以去我的另一篇博客https://blog.csdn.net/weixin_49692699/article/details/107822937 查看。

②、完整代码

#include <iostream>
#include <cmath>
#include <queue>
using namespace std;
int main() {
//输入 
	int n;
	cin>>n;
	int arr[n];
	for(int i=0;i<n;i++) 
		cin>>arr[i];

//各数位数字桶 
	queue<int> RaS0 , RaS1 , RaS2 , RaS3 , RaS4 , RaS5 , RaS6 , RaS7 , RaS8 , RaS9;

	for(int i=0;i<=20;i++) {

	//排序到第二十位 
		for(int j=0;j<n;j++) {
			switch(arr[j]/(int)pow(10,i)%10) {
	
			//比较各数的数位,并放入对应的队
				case 0: RaS0.push(arr[j]);break;
				case 1: RaS1.push(arr[j]);break;
				case 2: RaS2.push(arr[j]);break;
				case 3: RaS3.push(arr[j]);break;
				case 4: RaS4.push(arr[j]);break;
				case 5: RaS5.push(arr[j]);break;
				case 6: RaS6.push(arr[j]);break;
				case 7: RaS7.push(arr[j]);break;
				case 8: RaS8.push(arr[j]);break;
				case 9: RaS9.push(arr[j]);break;
			}
		}

		//原数组下标 
		int index=0;

		for(int j=0;j<10;j++) {

			switch(j) {

			//存入第j各队中的数字 
				case 0: {
					while(!RaS0.empty()) {
						arr[index++]=RaS0.front();
						RaS0.pop();
					}
					break;
				}
				case 1: {
					while(!RaS1.empty()) {
						arr[index++]=RaS1.front();
						RaS1.pop();
					}
					break;
				}
				case 2: {
					while(!RaS2.empty()) {
						arr[index++]=RaS2.front();
						RaS2.pop();
					}
					break;
				}
				case 3: {
					while(!RaS3.empty()) {
						arr[index++]=RaS3.front();
						RaS3.pop();
					}
					break;
				}
				case 4: {
					while(!RaS4.empty()) {
						arr[index++]=RaS4.front();
						RaS4.pop();
					}
					break;
				}
				case 5: {
					while(!RaS5.empty()) {
						arr[index++]=RaS5.front();
						RaS5.pop();
					}
					break;
				}
				case 6: {
					while(!RaS6.empty()) {
						arr[index++]=RaS6.front();
						RaS6.pop();
					}
					break;
				}
				case 7: {
					while(!RaS7.empty()) {
						arr[index++]=RaS7.front();
						RaS7.pop();
					}
					break;
				}
				case 8: {
					while(!RaS8.empty()) {
						arr[index++]=RaS8.front();
						RaS8.pop();
					}
					break;
				}
				case 9: {
					while(!RaS9.empty()) {
						arr[index++]=RaS9.front();
						RaS9.pop();
					}
					break;
				}
			}
		}
	}

//输出 
	for(int i=0;i<n;i++)
		cout<<arr[i]<<' ';
	return 0;
}

5. 快速排序

①、排序思路

快速排序的基本思路是选一个数字,将比其小的数排左边,比其大的数排右边。

②、完整代码

#include <iostream>
using namespace std;
void QuickSort(int*,int,int);
int main() {

//输入数组长度及数组各项
	int n;
	cin>>n;
	int arr[n];
	for(int i=0;i<n;i++)
		cin>>arr[i];

//升序排列
	QuickSort(arr,0,n-1);
	for(int i=0;i<n;i++)
		cout<<arr[i]<<' ';

//输出排序好的数组
	return 0;
}
void QuickSort(int a[],int l,int r) {

//开始递归
    if(l<r) {
    //没出错

        int mid=(l+r)/2;
        swap(a[mid],a[r]);
        int i=l,j=r-1;

	//小的数排左边,大的数排右边
        while(i<=j) {
            while(a[i]<a[r]) {
                i++;
            }
            while(a[j]>a[r]) {
                j--;
            }
            if(i<=j) {
                swap(a[i++],a[j--]);
            }
        }
        swap(a[i],a[r]);
        QuickSort(a,l,i-1);
        QuickSort(a,i+1,r);
    }
}

③、思路延伸

题目描述:
给定一个长度为n(1<=n<=100000)的序列,保证序列中的数不重复,问第k(1<=k<=n)小的元素是多少。
内存限制:128 MiB
时间限制:50 ms

输入格式:
第一行两个个整数n,k。
接下来一行n个数,表示这个序列。
输出格式:
输出仅一行,表示第k小的元素。
题目分析:
我们在排序中选择该元素,则该元素在该轮排序后一定排在序列全部有序后的位置上,如:

2 1 5 4 3
选5排序
一轮后: 2 1 3 4 5
排序完: 1 2 3 4 5
5在第一轮已经找到了它的位置

我们就可以借此来缩小排序次数,即:

if(i==m) return a[i]; 
else if(i>m) return QuickSort(a,l,i-1);
else return QuickSort(a,i+1,r);

参考代码:

#include <iostream>
using namespace std;
int m;
int QuickSort(int a[],int l,int r) {
    if(l==r) return a[l];
		else if(l<r) {
        int mid=(l+r)/2;
        swap(a[mid],a[r]);
        int i=l,j=r-1;
        while(i<=j) {
            while(a[i]<a[r]) {
                i++;
            }
            while(a[j]>a[r]) {
                j--;
            }
            if(i<=j) {
                swap(a[i++],a[j--]);
            }
        }
        swap(a[i],a[r]);
        if(i==m) return a[i]; 
        else if(i>m) return QuickSort(a,l,i-1);
        else return QuickSort(a,i+1,r);
    }
}
int main() {
	int n;
	cin>>n>>m;
	m--;
	int arr[n];
	for(int i=0;i<n;i++)
		cin>>arr[i];
	cout<<QuickSort(arr,0,n-1);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个使用JSP实现排序的程序: 1. 创建一个JSP页面,命名为sort.jsp,并在页面中添加以下代码: ```jsp <%@ page language="java" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>排序</title> </head> <body> <h1>排序算法演示</h1> <form method="post" action="sort.jsp"> <label>输入待排序的数字,用逗号分隔:</label> <input type="text" name="numbers"> <input type="submit" value="排序"> </form> <% // 接收表单提交的数据 String numbersString = request.getParameter("numbers"); if (numbersString != null && !numbersString.isEmpty()) { // 将输入的数字字符串转换为整型数组 String[] numbersArray = numbersString.split(","); int[] numbers = new int[numbersArray.length]; for (int i = 0; i < numbersArray.length; i++) { numbers[i] = Integer.parseInt(numbersArray[i]); } // 调用排序算法进行排序 // 这里使用冒泡排序算法作为示例 for (int i = 0; i < numbers.length - 1; i++) { for (int j = 0; j < numbers.length - 1 - i; j++) { if (numbers[j] > numbers[j + 1]) { int temp = numbers[j]; numbers[j] = numbers[j + 1]; numbers[j + 1] = temp; } } } // 输出排序后的结果 out.println("<p>排序结果为:</p>"); out.println("<ul>"); for (int i = 0; i < numbers.length; i++) { out.println("<li>" + numbers[i] + "</li>"); } out.println("</ul>"); } %> </body> </html> ``` 2. 在排序算法演示页面中,用户可以输入一组数字,用逗号分隔。当用户点击“排序”按钮时,将会提交表单数据到sort.jsp页面。在sort.jsp页面中,我们首先接收表单提交的数据,然后将输入的数字字符串转换为整型数组。接着,我们调用排序算法进行排序,这里使用冒泡排序算法作为示例。最后,我们输出排序后的结果。 可以根据需要使用其他排序算法,例如插入排序、选择排序、快速排序等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值