java实现---选择排序---堆排序

选择排序和堆排序

选择排序

  • 选择排序就是在一个元素集合中
  1. 选择一个最大的数据元素
  2. 如果它不是最后一个元素,则将它与这组元素的最后一个交换
  3. 接着在剩余的集合元素中重复步骤,直到集合剩余1个元素
public static void SelectSort(int arr[]){
        int i,j;
        for(i = arr.length;i > 0;i--){  // i 表示数组的最后一个元素的位置,
        //当把最大的元素放在该位置后,则 i--,往前走一步,即在剩下的元素中重复步骤
            int max =  0;   // 表示最大元素
            for(j = 0;j < i;j++){   从第一个开始遍历选择出最大的元素
                if(arr[j]>arr[max]){
                    max = j;
                }
            }
//            Swap(arr[max],arr[i-1]);  //交换最大的元素,使其放在最后面
            int temp = arr[max];
            arr[max] = arr[i-1];
            arr[i-1] = temp;
        }
    }
  • 两边同时开始,往中间找;
  • 找到最小的放在左边,找到最大的放在右边
public static void SelectSort(int arr[]){
    int left = 0,right = arr.length-1;
    while(left<right){  //表示元素还没有遍历完
        int j;
        int min = left,max = right;
        for(j = left+1;j<=right;j++){
            if (arr[j]>arr[max]){
                max = j;
            }
            if (arr[j] < arr[min])
            {
                min = j;
            }
        }
            int temp = arr[left];
            arr[left] = arr[min];
            arr[min] = temp;
        if (max == left){
            max = min;
        }
        int temp1 = arr[right];
        arr[right] = arr[max];
        arr[max] = temp1;
        left++;
        right--;
    }
}

堆排序

  • 创建堆:升序—>大堆,降序—>小堆
  1. 把堆顶array[0]元素和当前最堆的最后一个元素交换,堆元素个数减1;
  2. 由于第1步后,根节点不再满足堆定义,向下调整根结点 ,把一棵完全二叉树调整为堆。
  3. 所以,整个过程分为两步:建堆;然后,循环起来
void HeapSort(int arr[], int size)
{
    int i = 0;
    //1.建大堆(升序)
    CreateHeap(arr,size);
    for (i = 0; i < size; i++)
    {
         Swap(&arr[0], &arr[size - 1 - i]);
         AdjustDown(arr, size - i - 1, 0);
    }
}
  • 建堆过程
void CreateHeap(int arr[], int size)
{
    //从最后一个非叶子节点-->0
    //最后一个节点的双亲节点
    //[size-1][]
    //不断地进行向下调整
    for (int i = size / 2 - 1; i >= 0; i--)
    {
         AdjustDown(arr, size, i);
    }
}
void AdjustDown(int arr[], int size, int root)
{
    int left = 2 * root + 1;
    int right = 2 * root + 2;
    //叶子节点||满足堆的性质
    //没有左右孩子
    //因为完全二叉树,没有左孩子
    //左孩子下标越界
    if (left >= size){
         return;
    }
    //找到左右孩子中,谁是最大的(可能没有右孩子)
    int max = left;
    if (right<size&&arr[right]>arr[left]){
         max = right;
    }
    //根据[root]>=[最大的孩子],调整结束
    //否则,交换[root][最大的孩子]
    //继续对进行[最大的孩子]向下调整
    if (arr[root] >= arr[max]){
         return;
    }
    Swap(arr + root, arr + max);
    AdjustDown(arr, size, max);
}

猜你喜欢

转载自blog.csdn.net/WZL995/article/details/84790141