冒泡排序算法:主要从头(或从尾)依次比较相邻两个算法,经过一次多伦的比较交换,最小的值会优先排好。
static void bubbleSort(int[] data){
int temp;
for (int i = 1; i < data.length; i++) {
for (int j = 0; j < data.length-i; j++) {
if (data[j]>data[j+1]) {
temp=data[j+1];
data[j+1]=data[j];
data[j]=temp;
}
}
System.out.print(i+"次排序:");
for (int j = 0; j < data.length; j++) {
System.out.print(" "+data[j]);
}
System.out.println("/n");
}
}
复制代码
假设输入的值是:118,101,105,127,112。那么打印结果如下:
1次排序: 101 105 118 112 127 2次排序: 101 105 112 118 127 3次排序: 101 105 112 118 127 4次排序: 101 105 112 118 127 复制代码
快速排序算法:取一个值(通常为数组第一个元素或中间的元素)作为分界值。从数组右侧(尾部)依次取出元素与中间值比较,直到有小于分界值的元素i,然后从左侧开始,依次取出元素与中间值比较,直到有大于中间值的元素j,交换元素i和j的位置。但元素j的位置小于元素i的位置时,以元素j的位置为分界处重复上述操作(递归);
static void quickSort(int[] data,int begin,int end){
int left=begin,right=end;
int temp=data[(right+left)/2],value;
while (left<right) {
while (data[right]>temp) {
right--;
}
while (data[left]<temp) {
left++;
}
if (left<=right) {
value=data[left];
data[left]=data[right];
data[right]=value;
right--;
left++;
}
for (int i = 0; i < data.length; i++) {
System.out.print(" "+data[i] );
}
System.out.println("");
if (left==right) {
left++;
}
if (begin<right) {
quickSort(data,begin,left-1);
}
if (left<end) {
quickSort(data, right+1, end);
}
}
}
复制代码
假设数组元素为:118,101,105,127,112。那么打印结果如下:
105 101 118 127 112 101 105 118 127 112 101 105 118 112 127 101 105 112 118 127 复制代码
选择排序主要思想是遍历数组,选择数组中最小的元素放在第一个位置,第二小放在第二个位置,依次类推。
下面是算法的实现:
static void selectSort(int[] data) {
int temp; //用于交换数据的临时变量
for (int i = 0; i < data.length - 1; i++) {
//从i+1位置开始,与i的位置比较
for (int j = i + 1; j < data.length; j++) {
//如果j的位置元素小于i的值,则与i位置的元素交换
//这样就保持了i位置相对于后面的元素都是最小的
if (data[i] > data[j]) {
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
//将每次排序后的元素打印出来,方便查看
System.out.print(i+": ");
for (int j = 0; j < data.length; j++) {
System.out.print(" "+data[j]);
}
System.out.println();
}
}
复制代码
假如排序的数据为:118,101,105,127,112。那么打印出来的结果如下所示:
0: 101 118 105 127 112 1: 101 105 118 127 112 2: 101 105 112 127 118 3: 101 105 112 118 127 复制代码
堆排序相对于选择排序来说,比较复杂,主要是堆的构造过程(大根堆和小更堆)。然后选择堆的根节点与最后一个叶节点交换,并输出交换后最后一个叶节点(不再参与后面的堆构造过程)。重新构造堆得反复过程。
堆结构:堆结构是一种树结构,准备说法是完全二叉树,因为涉及到完全二叉树的一些特性,假设树有n个节点,第m个节点具有如下特性:
大根堆:如果按照从小到大的顺序排序,要求非叶节点的数据要大于或等于左右子树。
小根堆:如果按照从到到小的顺序排序,要求非叶节点的数据要小于或等于子树。
static void headSort(int[] data,int n){
int i,j,h,k;
int temp;
//将数组构建成大根堆
for (i=n/2-1;i>=0;i--) {
while (2*i+1<n) { //第i个元素有右子树(意味着也有左子树)
j=2*i+1; //左子树下标
if (data[j]<data[j+1]) { //左子树小于右子树
j++; //j指向右子树
}
//i元素与左右子树最大值进行比较,构造大根堆
if (data[i]<data[j]) {
temp=data[i];
data[i]=data[j];
data[j]=temp;
i=j;//交换会导致子树堆结构被破坏,需要重新构造
}else {
break;//子树堆未被破坏
}
}
}
System.out.print("原始数据构造成的堆:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
for(i=n-1;i>0;i--){
//堆得根第一个元素(数值最大)与最后一个元素(i元素,数值最小)交换
temp=data[0];
data[0]=data[i];
data[i]=temp;
k=0;
//每一步排序后需要重新构造堆,算法与上面构造初始堆是一致的
while (2*k+1<i) {
j=2*k+1;
if (data[j+1]<i) {
j++;
}
if (data[k]<data[j]) {
temp=data[k];
data[k]=data[j];
data[j]=temp;
k=j;
}else {
break;
}
}
System.out.print("第"+(n-i)+"次排序结果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
复制代码
假如排序的数据为:118,101,105,127,112。那么打印出来的结果如下所示:
原始数据构造成的堆: 127 118 105 101 112 第1次排序结果: 118 112 105 101 127 第2次排序结果: 112 101 105 118 127 第3次排序结果: 105 101 112 118 127 第4次排序结果: 101 105 112 118 127 复制代码
归为选择排序算法估计就是每次挑堆中最大(或最小)的元素输出。
插入排序主要是后面元素与前面排序好的元素比较,然后插入到合适的位置。
算法实现:
static void insetSort(int[] data){
int temp;
for (int i = 1; i < data.length; i++) {
temp=data[i];//保存i元素,下面元素后移会覆盖数组i下标的值
int j=i-1;
while(j>=0&&temp<data[j]){//i元素与依次与前面比较,直到大于前面元素为止
data[j+1]=data[j];//前面元素后移,方便i元素插入
j--;
}
data[j+1]=temp;
System.out.print("第"+i+"次排序结果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
复制代码
假如排序的数据为:118,101,105,127,112。那么打印出来的结果如下所示:
第1次排序结果: 101 118 105 127 112 第2次排序结果: 101 105 118 127 112 第3次排序结果: 101 105 118 127 112 第4次排序结果: 101 105 112 118 127 复制代码
主要是将有n个元素的数组分成n/2个数字序列,第1个数据和第n/2+1数据组成一对,一对数据进行比较,后者大则调换位置进行排序。然后n/4,n/8..重复排序,直到最后n/(2*k)=1,进行插入排序算法进行排序。Shell排序比较适合数组元素比较多情况。
static void shellSort(int[] data){
int x=0;
int temp;
for (int n = data.length/2; n >=1; n/=2) {//解决序列问题,即分组
int j;
for (int i = n; i < data.length; i++) {
temp=data[i];
j=i-n;//j坐标所在元素与i坐标所在元素成对
while (j>=0&&temp<data[j]) {
data[j+n]=data[j];
j-=n;
}
data[j+n]=temp;
System.out.print("第"+(x++)+"次排序结果:");
for (int l = 0; l < data.length; l++) {
System.out.print(" "+data[l]);
}
System.out.println();
}
}
}
}
复制代码
这里特意将打印信息,放到第一个循环内,可以清楚看出序列排序。假设属于数组为:118,121,105,127,112,30。 则打印结果如下:
//因为共分成6/2=3对序列,所以下标3、0,4、1,5、2一起组成3对序列,进行比较交换 //105-127 第0次排序结果: 118 121 105 127 112 30 //121-112 第1次排序结果: 118 112 105 127 121 30 //102-30 第2次排序结果: 118 112 30 127 121 105 //此时。6/4=1对序列,采用插入排序算法 第3次排序结果: 112 118 30 127 121 105 第4次排序结果: 30 112 118 127 121 105 第5次排序结果: 30 112 118 127 121 105 第6次排序结果: 30 112 118 121 127 105 第7次排序结果: 30 105 112 118 121 127 复制代码