什么是排序?
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
排序分类
排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。
常见的排序算法讲解
1、插入排序
/**
* 算法思想
* 向一个已经排好序的数组中进行插入,初始排好序的数组是只有第一个元素。从原始数组中依次获取元素,从排好序数组的最右边开始
* 比较,如果大于该元素就停止,否则交换即可。
* @author Administrator
*
*/
public class CharuSort {
private static int[] arr={12,6,3,24,100};
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 1; i < arr.length; i++) {
int cur=arr[i];//当前需要和排好序数组比较的数值
//寻找本次插入的位置index,最终完成交换
int index=i;//默认就是当前位置
for (int j = i-1; j >=0; j–) {
if(cur>arr[j]){
break;
}
else{
index=j;
arr[j+1]=arr[j];
}
}
arr[index]=cur;
}//for
for (int i = 0; i < arr.length; i++)
System.out.println(arr[i]);
}
}
2、选择排序
/**
* 算法思想
* 每次从当前未排序序列中找到最小值,放到第i个位置,i表示已排序的长度
* @author Administrator
*
*/
public class SelectSort {
private static int[] arr={12,6,3,24,100};
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < arr.length; i++) {
int minIndex=i;
for (int j = i+1; j < arr.length; j++) {
if(arr[j]<arr[minIndex]){
minIndex=j;
}
}//neifor
//最小值元素与当前第i个元素交换,完成本次最小值安放
int tmp=arr[i];
arr[i]=arr[minIndex];
arr[minIndex]=tmp;
}//for
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
3、冒泡排序
/**
* 冒泡排序思想
* 跟选择排序很像,一共也是n次,每一次都将最大的元素放到最后,而选择是将最小的元素放到最前
* @author Administrator
*
*/
public class BubbleSort {
private static int[] arr={12,6,3,24,100};
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 0; i < arr.length; i++) {
for (int j =0; j < arr.length-i-1; j++) {
if(arr[j]>arr[j+1]){
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
}
}//for
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
4、快速排序
/**
*选择一个基准元素,然后用这个元素将待排序数组分成两部分,
*一部分在左边,都比基准元素小,一部分在右边都比基准元素大。针对左右两边的数列重复该方法
*关于基准元素的选取随便,一般选取本数组最后一个或者第一个
* @author Administrator
*
*/
public class QuickSort {
private static int[] arr={12,6,3,24,100};
public static void main(String[] args) {
// TODO Auto-generated method stub
quick(arr,0,arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
public static void quick(int[] arr,int start,int end){
int pivot=arr[start];//选取基准元素
int left=start;
int right=end;
if(start<end){
//只要left<right就一直比较
while(left<right){
//从做找到第一个比pivot大的移动到右边
while(start<end&&arr[left]<pivot){
left++;
}
//找到第一个比pivot小的移动到左边
while(start<end&&arr[right]>pivot){
right--;
}
//交换left和right
int tmp=arr[left];
arr[left]=arr[right];
arr[right]=tmp;
}
//当left=right时候退出循环,这样大的在右,小在左,当前left位置赋值为pivot
arr[left]=pivot;
quick(arr,start,left-1);
quick(arr,right+1,end);
}
}
}
5、归并排序
思想:(1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
(2)设定两个指针,最初位置分别为两个已经排序序列的起始位置
(3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
(4)重复步骤3直到某一指针达到序列尾
(5)将另一序列剩下的所有元素直接复制到合并序列尾
直观感受图:
算法实现:
/**
* 归并排序
* 思想:将原数组划分为两个子数组,对两个子数组排好序,然后再对两个排好序的子数组合并操作。子数组划分到只有一个元素的时候返回子数组即可。
* 里面应用了递归的思想
*
* (1)申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
(2)设定两个指针,最初位置分别为两个已经排序序列的起始位置
(3)比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
(4)重复步骤3直到某一指针达到序列尾
(5)将另一序列剩下的所有元素直接复制到合并序列尾
@author Administrator
*
*/
public class MergeSort {
private static int[] arr={12,6,3,24,100};
public static void main(String[] args) {
// TODO Auto-generated method stub
mergeSort(arr,0,4);
for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]); }
}
/*arr 归并排序的数组,low数组首元素下标,high末尾元素下标
*/
public static void mergeSort(int[] arr,int low ,int high){
//如果low=high表示该数组剩下一个元素了就返回
if(low<high){
int mid=(high+low)/2;//以该下标为界分为两个子数组,二分法取下标
mergeSort(arr,low,mid);
mergeSort(arr,mid+1,high);
//将两个已经排好序的子数组归并
merge(arr,low,mid,high);}
}
/**- 归并
- @param arr2
- @param low
- @param mid
@param high
*/
public static void merge(int[] arr, int low, int mid, int high) {
// 申请空间,创建临时数组存储归并结果,长度是二者之和
int[] temp=new int[high-low+1];
//定义两个变量,存储两个排好序的子数组目前位置
int i=low;
int j=mid+1;
//定义临时数组目前存了多少个元素
int k=0;
//依次比较两个子数组元素大小,小的存储到temp中,直到某个子数组遍历完
while(i<=mid&&j<=high){
if(arr[i]<arr[j]){
temp[k++]=arr[i++];
}
else{
temp[k++]=arr[j++];
}}
//将某个有剩余元素的子数组元素放入temp
if(i<=mid){
for(int t=i;t<=mid;t++){
temp[k++]=arr[t];
}
}
if(j<=high){
for(int t=j;t<=high;t++){
temp[k++]=arr[t];
}}
//将temp数组元素覆盖原数组arr
for(int t=0;t<temp.length;t++){
arr[t+low]=temp[t];
}
}
}