(1、冒泡排序 2、选择排序 3、插入排序 4、归并排序 5、快速排序 6、堆排序 7、希尔排序)
1、冒泡排序
原理:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
public static void bubble(int [] a){
for(int i=0;i<a.length-1;i++){
for(int j=0;j<a.length-1-i;j++){
if(a[j]>a[j+1]){
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
}时间复杂度:若数组为正序,则一轮比较即可完成排序,时间复杂度为O(n)
public static void select(int [] a){
for (int i = 0; i < a.length; i++) {
int min = a[i];
int n=i;
for(int j=i+1;j<a.length;j++){
if(a[j]<min){
min = a[j];
n = j;
}
}
a[n] = a[i];
a[i] = min;
}
}
时间复杂度:O(n^2)
public static void insert(int [] a){
int temp=0 ;
int j=0;
for(int i=0;i<a.length;i++)
{
temp=a[i];
//如果第i个数比前面的数小,就让前面的数向后移
for(j=i;j>0&&temp<a[j-1];j --)
{
a[j]=a[j-1];
}
a[j]=temp;
}
}时间复杂度:O(n^2)
以上是时间复杂度为O(n^2)的排序
public static void sort(int[] data, int left, int right) {
if (left < right){
//找出中间索引
int center = (left + right) / 2;
//对左边数组进行递归
sort(data, left, center); //递归时先调用的后返回,后调用的先返回,因此形参的值也跟随,根据栈的原则
//对右边数组进行递归
sort(data, center + 1, right); /*当center是0的时候,left=right,因此sort不再执行,继续*/
//合并
merge(data, left, center, right);
}
}
public static void merge(int[] data, int left, int center, int right){
int[] tmpArr = new int[data.length];
int mid = center + 1;
//third记录中间数组的索引
int third = left;
int tmp = left;
while (left <= center && mid <= right){
//从左右两个数组中取出小的放入中间数组,
if (data[left]-data[mid]<= 0){
tmpArr[third++] = data[left++];
} else{
tmpArr[third++] = data[mid++];
}
}
//比较后剩余的其他数字部分依次放入中间数组
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
//将中间数组中的内容复制拷回原数组
//(原left~right范围的内容复制回原数组)
while (tmp <= right){//已经排序好的数组
data[tmp] = tmpArr[tmp++];
}
System.out.println("merge");
}
public static void quickSort(int[] data, int start, int end) {
int i = start; //相当于i,左 索引
int j = end; //相当于j, 右 索引
if (i >= j) { // 判断是否到中间了 ,到中间返回
return; //返回
}
//确定指针方向的逻辑变量,也就是从左搜索还是向右搜索
boolean flag=true; //false:左->右 true:右->左
while (i != j) { //如果i==j证明第一趟结束,每趟的标准值仅是一个,例如第一趟被比较值为49,
if (data[i] > data[j]) {
//交换数字 :所有比它小的数据元素一律放到左边,所有比他大的数据元素一律放到右边,
int temp = data[i];
data[i] = data[j];
data[j] = temp;
//只有经过数的交换后,才能把游标的移动位置改变,移动书序是交替改变
//决定下标移动,还是上标移动 ,游标更改 走下一个数据
flag = (flag == true) ? false : true;
// flag=!flag;
}
//将指针向前或者向后移动 ,第一次从左-》右,第二次从右-》左
if(flag) {//true,右---》左
j--;
}else{//false 左---》右
i++;
}
}
i--;
j++;
quickSort(data, start, i);
quickSort(data, j, end);
}
public static void heapSort(int [] data) {
System.out.println("开始排序");
int arrayLength = data.length;
//循环建堆
/*
* 9
* / \
* 79 46
* / \ /
* 30 58 49
*/
//针对完全二叉树,大顶堆,最顶端的值(0号索引)肯定是在没swap之前的最大的值,
//对其在数组里面进行排序交换,大的排在数组后面,虽然最大的在最上面,但是其他的数据并没有排好,因此,需要不停更换顶点,重新建堆,需要循环
for (int i = 0; i < arrayLength - 1 ; i++ ){//5 4 3 2 1
//建堆
builMaxdHeap(data, arrayLength - 1 -i);//-i的原因,就是数组中没经过一次循环,最大的数已经在数组的后面了,就不用在建堆了
//由于是大顶锥方式:锥顶是最大的数,交换堆顶和最后一个元素
System.out.print("交换锥顶前");
System.out.println(Arrays.toString(data));
swap(data, 0 , arrayLength - 1 - i);
System.out.print("交换锥顶后");
System.out.println(Arrays.toString(data));
}
}
private static void builMaxdHeap(int [] data, int lastIndex){//修建大顶堆
//从lastIndex处节点(最后一个节点)的父节点开始
//(lastIndex - 1)/2 为最后一个节点的父节点的索引(除根节点)
//都是从子节点开始判断 k的值分别是 5 3 1 索引号依次判断
/*
* 9
* / \
* 79 46
* / \ /
* 30 58 49
*/
for (int i = (lastIndex - 1) / 2 ; i >= 0 ; i--){//索引号从大的开始
//k保存当前正在判断的节点
int k = i;
//如果当前k节点的子节点存在,
//k * 2 + 1 判断当前节点的子节点
while (k * 2 + 1 <= lastIndex){//看当前要判断k的子节点是否存在。
//k节点的左子节点的索引
int biggerIndex = 2 * k + 1;
//如果biggerIndex小于lastIndex,即biggerIndex + 1
//代表k节点的右子节点存在
if (biggerIndex < lastIndex){//防止溢出
//如果右子节点的值较大,biggerIndex存储的都是最大节点索引
if(data[biggerIndex]-(data[biggerIndex + 1]) < 0){//左面的小于右面的
//biggerIndex总是记录较大子节点的索引,之后再和父亲比
biggerIndex++; //这是较大节点的索引号,也就是右节点的索引号
}
}
//如果k(父节点)节点的值小于其较大子节点(左右都有可能)的值,交换
if(data[k]-(data[biggerIndex]) < 0){
//交换它们
swap( data,k , biggerIndex);
//将biggerIndex赋给k,开始while循环的下一次循环,
//重新保证k节点的值大于其左、右子节点的值。
k = biggerIndex;//大节点的索引号,
}else{//满足的条件刚好是节点的值大于子节点的值
break;//刚好进入下一层循环
}
}
}
}
//交换data数组中i、j两个索引处的元素
private static void swap(int [] data, int i , int j){
int tmp = data[i];
data[i] = data[j];
data[j] = tmp;
}7、希尔排序
实现:
代码:
public void shellSort(int[] list) {
int gap = list.length / 2;
while (1 <= gap) {
// 把距离为 gap 的元素编为一个组,扫描所有组
for (int i = gap; i < list.length; i++) {
int j = 0;
int temp = list[i];
// 对距离为 gap 的元素组进行排序
for (j = i - gap; j >= 0 && temp < list[j]; j = j - gap) {
list[j + gap] = list[j];
}
list[j + gap] = temp;
}
gap = gap / 2; // 减小增量
}
}
(希尔排序的文字描述、图片、代码均来自-> 希尔排序 )
282



被折叠的 条评论
为什么被折叠?



