排序是计算机程序设计中的一项重要操作,其功能是指一个数据元素集合或序列重新排列成一个按数据元素某个数据项值有序的序列。
1:内排序:指的是待排序列完全存放在内存中所进行的排序。其又可分为五大类排序:选择排序、插入排序、交换排序、归并排序和分配排序。
2:外排序:指的是排序过程中还需要访问外部存储器的排序。
将待排序元素分为已排序(初始为空)和未排序两组,依次将未排序元素中值最小的元素放入到已排序的组别中。
for(int i = 0; i < arr.length - 1; i++) {
//进行n-1趟排序
int k = i;
for(int j = k + 1; j < arr.length; j++){
// 选最小的记录
if(arr[j] < arr[k]){
k = j; //记下目前找到的最小值所在的位置
}
}
//元素交换
if(i != k){
int temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
每次将一个待排的元素,按其关键字大小插入到前面已经排号序的子文件的合适位置,直到全部记录插入完成为止。
将n个待排序的元素看成一个有序表和一个无序表,开始时有序表中只包含有一个元素,无序表中有n-1个元素,将它的排序码依次跟有序表元素的排序码相比较,将它插入到有序表的适当位置,使之成为新的有序表。
public static void D-insertSort(int [] array){
for(int i=0;i<array.length;i++){
//有序[0,i)
//无序[i,array.length)
int j=i-1;
int key=array[i];
for(;j>=0 && key<array[j];j--){
array[j+1]=array[j];//元素后移
}
array[j+1]=key;//将key中的第i个元素插入到有序表中
}
/**
*
* @Title: buildHeap
* @Description: TODO(初始堆结构(完全二叉树的顺序结构))
* @param @param arr
* @param @return 参数
* @return int[] 返回类型
* @throws
*/
private int[] buildHeap(int[] arr){
//从最后一个节点array.length-1的父节点(array.length-1-1)/2开始,直到根节点0,反复调整堆
for(int i=(arr.length-2)/2;i>=0;i--){
setHeap(arr, i,arr.length);
}
return arr;
}
/**
*
* @Title: setHeap
* @Description: TODO(调整堆结构)
* @param @param arr
* @param @param t
* @param @param length 参数
* @return void 返回类型
* @throws
*/
private void setHeap(int[] arr,int t,int length){
int temp = arr[t];
for(int i=2*t+1; i<length-1; i=2*i+1){
//i为初始化为节点k的左孩子,沿节点较大的子节点向下调整
if(i<length && arr[i]<arr[i+1]){
//取节点较大的子节点的下标
i++; //如果节点的右孩子>左孩子,则取右孩子节点的下标
}
if(temp>=arr[i]){
//根节点 >=左右孩子中关键字较大者,调整结束
break;
}else{
//根节点 <左右孩子中关键字较大者
arr[t] = arr[i]; //将左右子结点中较大值array[i]调整到双亲节点上
t = i; //【关键】修改k值,以便继续向下调整
}
}
arr[t] = temp; //被调整的结点的值放人最终位置
}
/**
*
* @Title: heapSort
* @Description: TODO(进行堆排序)
* @param @param arr
* @param @return 参数
* @return int[] 返回类型
* @throws
*/
public int[] heapSort(int[] arr){
arr = buildHeap(arr); //初始建堆,array[0]为第一趟值最大的元素
for(int i=arr.length-1;i>1;i--){
int temp = arr[0]; //将堆顶元素和堆低元素交换,即得到当前最大元素正确的排序位置
arr[0] = arr[i];
arr[i] = temp;
setHeap(arr, 0,i); //整理,将剩余的元素整理成堆
}
return arr;
}
}
将两个有序表合并为一张有序表
顺序比较两个已经排序好的表的相应元素,小的移入到另一个表,重复上述步骤直到其中任意一个表都移动到另外一个表为止,
/**
*
* @Title: mergeSort
* @Description: TODO(归并排序)
* @param @param arr 待排数组
* @param @param left 左边
* @param @param right 右边
* @return void 返回类型
* @throws
*/
public static void mergeSort(int[] arr, int left, int right) {
if(null == arr) {
return;
}
if(left < right) {
//找中间位置进行划分
int mid = (left+right)/2;
//对左子序列进行递归归并排序
mergeSort(arr, left, mid);
//对右子序列进行递归归并排序
mergeSort(arr, mid+1, right);
//进行归并
merge(arr, left, mid, right);
}
}
/**
*
* @Title: merge
* @Description: TODO(进行归并操作)
* @param @param arr
* @param @param left 左边
* @param @param mid 中间
* @param @param right 右边
* @return void 返回类型
* @throws
*/
private static void merge(int[] arr, int left, int mid, int right) {
int[] tempArr = new int[arr.length];//临时数组
int leftStart = left;//左边开始下标
int rightStart = mid+1;//右边开始下标
int tempIndex = left;
while(leftStart <= mid && rightStart <= right) {
if(arr[leftStart] < arr[rightStart]) {
tempArr[tempIndex++] = arr[leftStart++];
} else {
tempArr[tempIndex++] = arr[rightStart++];
}
}
while(leftStart <= mid) {
tempArr[tempIndex++] = arr[leftStart++];
}
while(rightStart <= right) {
tempArr[tempIndex++] = arr[rightStart++];
}
while(left <= right) {
arr[left] = tempArr[left++];
}
}
通过对待排序序列从前往后,依次比较相邻元素的排序码,若发现逆序则交换,使排序码大的元素逐渐从前部移到尾部
/**
*
* @Title: BubbleSort
* @Description: TODO(冒泡排序)
* @param @param arr 待排数组
* @return void 返回类型
* @throws
*/
public static void BubbleSort(int[] arr) {
int temp;//定义一个临时变量
for(int i=0;i<arr.length-1;i++){
//冒泡趟数
for(int j=0;j<arr.length-i-1;j++){
if(arr[j+1]<arr[j]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
任取待排序序列中的某个元素作为标准,通过一次划分,将待排元素分为左右两个子序列,左子序列元素的排序码都小于基准元素的排序码,右子序列元素的排序码都大于或等于基准元素的排序码,接着分别对两个子序列继续进行划分,直到每一个序列只有一个元素为止。
/**
*
* @Title: quickSort
* @Description: TODO(快速排序)
* @param @param arr 待排数组
* @param @param left 左下标
* @param @param right 右下标
* @return void 返回类型
* @throws
*/
public void quickSort(int[] arr,int left,int right){
if (left<right){
int temp=arr[left];//基准位
while (left<right){
//右边,依次向左递减
while (left<right && arr[right]>temp){
right--;
}
if (left<right){
arr[left++]=arr[right];
}
//左边,依次向右递增
while (left<right && arr[left]<=temp){
left++;
}
if (left<right){
//元素交换
arr[right--]=arr[left];
}
}
arr[left]=temp;
quickSort(arr,left,temp-1);//递归调用左边部分
quickSort(arr,temp+1,right);//递归调用右边部分
}
}
先将整个待排元素序列分割为若干个子序列分别继续直接插入排序,待整个序列中的元素基本有序时再对整体元素进行一次直接插入排序。
public void sort() {
int temp;
for (int k = array.length / 2; k > 0; k /= 2) {
for (int i = k; i < array.length; i++) {
for (int j = i; j >= k; j -= k) {
if (array[j - k] > array[j]) {
temp = array[j - k];
array[j - k] = array[j];
array[j] = temp;
}
}
}
}
}