冒泡排序法口诀:
冒择路兮 快归堆
(冒泡排序)(选择排序)(插入排序法)(希尔排序)(快速排序)(归并排序)(堆排序)
1、什么是冒泡排序
依次比较相邻的两个数,将小数放在前面,大数放在后面。由于在排序过程中总是小数往前放,大数往后放,相当于气泡往上升,所以称作冒泡排序。原理简单不解释!
import java.util.Arrays;
public class Bubblesort{//冒泡排序法
static void bubblesort(int[] a){
int temp;
{
for (int i = 0; i < a.length; i++) {
for (int j = a.length - 1; j > i; j--){//跟相邻交换,大的
if (a[j] < a[j-1]){
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
}
}
}
System.out.print(Arrays.toString(a));
}
public static void main(String args[]){
bubblesort(new int[] { 8, 2, 4, 9, 3, 6, 7, 10 });
}
}
2.选择排序
每一趟从待排序的数据元素中选出最小(或最大)的一个元素,顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。就是第一次把老大挑出来,第二次挑二哥。。。
import java.util.Arrays;
public class SelectSort{
public static void selectSort(int[] data) {
for (int i = 0; i < data.length;i++) {
for (int j = data.length-1;j>i;j--){
if(data[j]<data[i]){
int temp=data[i];
data[i]=data[j];
data[j] = temp;
}
}
}
System.out.print(Arrays.toString(data));
}
public static void main(String[] args) {
selectSort(new int[] { 8, 2, 4, 9, 3, 6, 7, 10 });
}
}
3.插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序。每次处理就是将无序数列的第一个元素与有序数列的元素从后往前逐个进行比较,找出插入位置,将该元素插入到有序数列的合适位置中。就是逐个取出数据,插入组成有序系列。
public class InsertSort {
public static void main(String[] args) {
insertSort(new int[] { 8, 2, 4, 9, 3, 6, 7, 10 });
}
// 辅助函数
public static void dumpArray(int[] a) {
for (int index = 0; index < a.length; index++) {
System.out.print(a[index] + " ");
}
System.out.println("");
}
public static void insertSort(int[] a) {
// 输出原始数组
dumpArray(a);
for (int index = 1; index < a.length; index++){
int subIndex = index;
int currentData = a[index]; // 等待插入的数据
while ((subIndex > 0) && (a[subIndex - 1] > currentData)) {
a[subIndex] = a[subIndex - 1];
subIndex--;
}
a[subIndex] = currentData; // 插入到合适的位置
// 每次排序后也输出
dumpArray(a);
}
}
}
4.希尔排序
属于插入类排序,是将整个无序列分割成若干小的子序列分别进行插入排序。
排序过程:先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序;
然后取d2<d1,重复上述分组和排序操作;直至di=1,即所有记录放进一个组中排序为止。
public class ShellSort {
public static int[] a = { 10, 32, 1, 9, 5, 7, 12, 0, 4, 3 };
public static void main(String args[]) {
int i; // 循环计数变量
int Index = a.length;// 数据索引变量
System.out.print("排序前: ");
for (i = 0;i<Index-1; i++){
System.out.printf("%3s ", a[i]);
}
System.out.println("");
shellSort(Index-1); // 选择排序
System.out.print("排序后: ");// 排序后结果
for (i = 0; i <Index -1;i++){
System.out.printf("%3s ",a[i]);
}
System.out.println("");
}
public static void shellSort(int Index){
int i, j, k; // 循环计数变量
int Temp; // 暂存变量
boolean Change; // 数据是否改变
int DataLength; // 分割集合的间隔长度
int Pointer; //进行处理的位置
DataLength = (int)Index/2;//初始集合间隔长度
while (DataLength != 0) // 数列仍可进行分割
{
//对各个集合进行处理
for (j = DataLength; j < Index; j++) {
Change = false;
Temp = a[j]; // 暂存Data[j]的值,待交换值时用
Pointer = j - DataLength; // 计算进行处理的位置
// 进行集合内数值的比较与交换值
while (Temp < a[Pointer] && Pointer >= 0 && Pointer <= Index) {
a[Pointer + DataLength] = a[Pointer];
// 计算下一个欲进行处理的位置
Pointer = Pointer - DataLength;
Change = true;
if (Pointer < 0 || Pointer > Index)
break;
}
// 与最后的数值交换
a[Pointer + DataLength] = Temp;
if (Change) {
// 打印目前排序结果
System.out.print("排序中: ");
for (k = 0; k < Index; k++)
System.out.printf("%3s ", a[k]);
System.out.println("");
}
}
DataLength = DataLength / 2; // 计算下次分割的间隔长度
}
}
}
5.快速排序法
快速排序(Quicksort)是对冒泡排序的一种改进。由C. A. R. Hoare在1962年提出。
它的基本思想是:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
import java.util.Arrays;
public class Qk {
public static void main(String[] args) {
int[] c = { 4, 9, 23, 1, 45, 27, 5, 2 };
quickSort(c, 0, c.length - 1);
System.out.println(Arrays.toString(c));
}
public static void quickSort(int[] data,int low,int high){
int lowP=low;
int highP =high;
if(low>=high){
return;
}
int p = data[low];
while(low<high){
while(low < high && data[high]>p){
high--;
}
if(low < high){
int temp = data[low];
data[low]=data[high];
data[high]=temp;
}
while(low < high && data[low]<p){
low++;
}
if(low < high){
int temp = data[low];
data[low]=data[high];
data[high]=temp;
}
}
quickSort(data,lowP,low-1);
// 后半个子表递归排序
quickSort(data,high + 1, highP);
}
}
6.归并排序
归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。
然后再把有序子序列合并为整体有序序列。归并操作(merge),也叫归并算法,指的是将两个已经排序的序列合并成一个序列的操作。如
设有数列{6,202,100,301,38,8,1}
初始状态: [6] [202] [100] [301] [38] [8] [1]
比较次数 i=1 [6 202 ] [ 100 301] [ 8 38] [ 1 ] 3
i=2 [ 6 100 202 301 ] [ 1 8 38 ] 4
i=3 [ 1 6 8 38 100 202 301 ] 4
总计: 11次
下面是一个归并单元:
public static int[] mergeSort(int[] data1,int[] data2){
int[] temp=new int[data1.length+data2.length];
int i=0,j=0,iter=0;
for(;i<data1.length&&j<data2.length;){
if(data1[i]<=data2[j]){
temp[iter]=data1[i];
iter++;
i++;
}
else{
temp[iter]=data2[j];
iter++;
j++;
}
}
for(;i<data1.length;i++,iter++){
temp[iter]=data1[i];
}
for(;j<data2.length;j++,iter++){
temp[iter]=data2[j];
}
return temp;
}
下面是本人用递归加归并实现的完整归并算法。
import java.util.Arrays;
public class MergeSort{
public static void splitArray(int[] a){
int[][] array =new int[a.length][1];
for(int i =0;i<a.length;i++){
array[i][0]=a[i];
}
while(array.length != 1){
int b[][]= new int[(array.length-1)/2+1][];
for(int i=0;i<array.length/2*2;i++){
if(array.length-i*2 > 1){
b[i] = mergeSort(array[2*i],array[2*i+1]);
}
}
if(array.length%2!=0){
b[b.length-1] = array[array.length-1];
}
array = b.clone();
}
System.out.println(Arrays.toString(array[0]));
}
public static int[] mergeSort(int[] data1,int[] data2){
int[] temp=new int[data1.length+data2.length];
int i=0,j=0,iter=0;
for(;i<data1.length&&j<data2.length;){
if(data1[i]<=data2[j]){
temp[iter]=data1[i];
iter++;
i++;
}
else{
temp[iter]=data2[j];
iter++;
j++;
}
}
for(;i<data1.length;i++,iter++){
temp[iter]=data1[i];
}
for(;j<data2.length;j++,iter++){
temp[iter]=data2[j];
}
return temp;
}
public static void main(String args[]){
//怎么利用归并单元,给一个数组排序
int array[] = {6,202,100,301,38,8,1};
splitArray(array);
}
}
7.堆排序堆积排序(Heapsort)是指利用堆积树(堆)这种资料结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。
public class HeapSortTest {
/*
* 将数组调整为小根堆,即由小到大排序
*/
public static int[] heap = new int[] { 1,3,7,5,2,8,4,6,10,9};
public static void main(String[] args) {
int temp;
// 创建堆(对该堆进行简单的排序)
CreateHeap();
for (int i = heap.length - 1; 0 < i; i--) {
temp = heap[0];
heap[0] = heap[i];
heap[i] = temp;
// 展示每次排序后的结果
for (int j = 0; j < heap.length; j++) {
System.out.print(heap[j] + " ");
}
System.out.println();
// 从堆顶进行调整,使未排序堆中最大关键字到堆顶
AdjustHeap(0,i);
}
}
// 调整堆使其堆顶为未排序堆中最大关键字
public static void AdjustHeap(int location,int unSortlength) {
int temp;
int tempLoc;
//确保左右节点存在
if ((tempLoc = (location + 1) * 2) < unSortlength){
// 判断左右节点大小
if (heap[tempLoc] >= heap[tempLoc - 1]) {
// 判断父节点与子节点的大小,若父节点小,则与大的子节点换位
if (heap[location] < heap[tempLoc]) {
temp = heap[location];
heap[location] = heap[tempLoc];
heap[tempLoc] = temp;
// 递归法对换位后的子节点及其子节点进行调整
AdjustHeap(tempLoc,unSortlength);
}
} else {
// 左节点大于右节点
if (heap[location] < heap[tempLoc - 1]) {
temp = heap[location];
heap[location] = heap[tempLoc - 1];
heap[tempLoc - 1] = temp;
// 递归法对换位后的子节点及其子节点进行调整
AdjustHeap(tempLoc - 1,unSortlength);
}
}
}
// 确保左节点存在
else if ((tempLoc = (location + 1) * 2 - 1) < unSortlength) {
// 与左节点进行比较
if (heap[location] < heap[tempLoc]) {
// 左子节点大于父节点,将两者进行换位
temp = heap[location];
heap[location] = heap[tempLoc];
heap[tempLoc] = temp;
AdjustHeap(tempLoc,unSortlength);
}
}
}
// 创建堆(对该堆进行简单的排序)
public static void CreateHeap() {
for (int i = heap.length - 1; i >= 0; i--) {
AdjustHeap(i,heap.length);
}
}
}