《算法设计与分析》 实验1

《算法设计与分析》 实验作业1

1. 冒泡排序

冒泡排序

比较相邻的元素,前一个比后一个大(或者前一个比后一个小)调换位置

public static void bubbleSort(int a[]) {
   int n = a.length;
   for (int i = n - 1; i > 0; i--) {
       for (int j = 1; j <= i; j++) {
           if (a[j] < a[j - 1]) {
               int t = a[j];
               a[j] = a[j - 1];
               a[j - 1] = t;
           }
       }
   }
}

2. 选择排序

选择排序
思想:

  1. 找到一个最小值与最前面一个数进行交换
  2. 在第2个数~最后一个数中,找到次小值与第二个数进行交换
  3. 依次类推… 直到最后
public static void choiceSort(int a[]) {
	int n = a.length;
    for (int i = 0; i < n; i++) {
        int idx = i;//记录每次需要交换的点的下标
        //在 i+1 到 n-1 中的数寻找最小值的下标
        for (int j = i + 1; j < n; j++) {
            if (a[j] < a[idx]) {
                idx = j;//记录最小值的
            }
        }
        int t = a[i];
        a[i] = a[idx];
        a[idx] = t;
    }
}

3. 插入排序

插入排序
插入排序思想:前面设置好一个已经排好序的部分,如上图橙色部分所示,依次遍历未排序的部分,将当前遍历到的数抽出来,插入到已经排好序的数组中。

public static void insertSort(int a[]) {
    int n = a.length;
    for (int i = 1; i < n; i++) {
        int t = a[i];//暂存a[i]的值
        int idx = i - 1;//已经排好序数组的最后一个位置
        //从idx往前遍历,保证不越界,并且大于a[i]
        while (idx >= 0 && a[idx] > t) {
        	//将这些数往后挪一个位置出来,腾出位置放a[i]
            a[idx + 1] = a[idx];
            idx--;
        }
        //因为上面的while循环是要求满足a[idx]>t,所以结束的时候说明a[i] > a[idx],所以将a[i]的值放到idx + 1的位置。
        a[idx + 1] = t;
    }
}

4. 堆排序

堆排序
上图是大顶堆的演示,原理是相同的。

堆:一棵完全二叉树。
完全二叉树:除了最后一层不满,上面是满二叉树,但最后一层从左到右。

独特的存储方式:
在这里插入图片描述

作业题目是小顶堆。
个人习惯:以下标1作为堆顶元素,感觉比用下标0作为堆顶元素舒服,2x和2x+1,如果是0的话,左子节点也是0,需要操作一波,我比较懒,所以就,dddd

解释一下代码中的 down(x) 操作:
down顾名思义,即将当前节点往下调整,因为要维护一个堆,就要保证
根节点是小于等于左右子节点 (小顶堆)
即: a [ x ] ≤ a [ 2 ∗ x ] a[x] ≤ a[2 * x] a[x]a[2x] && a [ x ] ≤ a [ 2 ∗ x + 1 ] a[x] ≤ a[2 * x + 1] a[x]a[2x+1]
所以要从前往后遍历一遍,找到左右子节点和根节点的最小值,如果最小值出现在左右字节点中,就要与根节点位置进行交换。递归的down就行

建堆的两种方式:
1. O(nlogn)建堆,一个一个点插入。
在堆中插入一个数x:
heap[++size] = x;//将需要插入的数放到堆的最后面,进行up操作
up(x);
2. O(n) 的方式建堆

public class HeapSort {
    public static int n;
    public static int h[] = {0, 25, 30, 11, 7, 22, 16, 18, 33, 40, 55};
    public static void down(int u){
        int t = u;
        if (u << 1 <= n && h[t]> h[u << 1]) t = u << 1;
        if ((u << 1 | 1) <= n && h[t] > h[u << 1 | 1]) t  = u << 1 | 1;
        if (t != u) {
            int tmp = h[u];
            h[u] = h[t];
            h[t] = tmp;
            down(t);
        }
    }
    public static void main(String args[]){
        n = h.length;
        n--;
        //建堆
        for (int i = n / 2; i >= 1; i--) down(i);

        int len = n;
        //依次提出堆顶元素
        for (int i = 1; i <= len; i++) {
            System.out.print(h[1] + " ");
            h[1] = h[n--];//删除堆顶元素
            down(1);//将堆顶元素down一遍
        }
    }
}
  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值