选择排序---每次都是最优解


1,思路

选择排序基于一种简单的思路:每一次选择都选最,直到把所有的数据都排

例如对于如下0,9随机数组 

[8, 6, 3, 5, 9, 1, 0, 4, 2, 7]

其排序结果是

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

对于任何数组,下标本身就是一个排序

第一位

第二位

………

N

那么选择排序的过程是怎样的呢?

简单来说,排序过程就像一个店小二的吆喝像这样 “谁是第一名,来来来,到这来“第二名是哪个,过来,过来...”

过程如下:

① 找到最小的数0存放在第一位

 

② 找到第二小的1存放在第二位

 

③ 直到排完所有数据.

 

实际上选择排序的逻辑是在一个数组中进行。这样比较省内存。一个数组中,不可避免的就会出现一个问题,数据交换,过程如下

① 创建临时变量 5 存入到变量中

 

② 将第一位赋值为0

 

③ 将第五位赋值5

 

2代码片段如下

① 交换逻辑

 

② 选择排序逻辑

 

 

③ 排序过程图: 

 

绿色是以完成排序红色为本次排序交换部分,黑色为无操作部分

3时间复杂度分析:

对于长度10的数组入上图所示

第一行比较了 9

第二行比较 8 次

      .

      .

      .

最后一行比较了1 次

数M=9+8 +……+1

10换成N,对于任意N长度数组,总比较次数为

N-1+N-2+…+2+1=N*(N-1+1)/2= N2/2

综上,选择排序的时间复杂度为O(N2)

 

4,特点

选择排序与输入无关,即无论输入数组是正序,倒序,还是乱序,他的时间复杂度都一样。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用优先队列求解0-1背包问题并输出最优解的C语言代码: ```c #include <stdio.h> #include <stdlib.h> // 优先队列结构体 typedef struct { int value; // 节点价值 int weight; // 节点重量 int level; // 节点层数 } Node; // 用于比较节点优先级的函数 int cmp(const void* a, const void* b) { const Node* nodeA = (const Node*)a; const Node* nodeB = (const Node*)b; double priorityA = (double)nodeA->value / nodeA->weight; double priorityB = (double)nodeB->value / nodeB->weight; if (priorityA < priorityB) { return 1; } else if (priorityA > priorityB) { return -1; } else { return 0; } } // 求解0-1背包问题并输出最优解 void knapsack(int n, int capacity, int* values, int* weights) { // 初始化优先队列 Node* queue = (Node*)malloc(n * sizeof(Node)); for (int i = 0; i < n; i++) { queue[i].value = values[i]; queue[i].weight = weights[i]; queue[i].level = 0; } qsort(queue, n, sizeof(Node), cmp); // 初始化最优解 int bestValue = 0; int* bestItems = (int*)calloc(n, sizeof(int)); // 迭代搜索 while (1) { // 取出队首节点 Node node = queue[0]; if (node.level == n) { // 搜索到叶子节点 if (node.value > bestValue) { bestValue = node.value; for (int i = 0; i < n; i++) { bestItems[i] = (node.weight >> i) & 1; } } } else { // 扩展左儿子节点(不选当前物品) Node left = node; left.level = node.level + 1; left.weight -= weights[left.level - 1]; queue[0] = left; qsort(queue, n, sizeof(Node), cmp); // 扩展右儿子节点(选当前物品) Node right = node; right.level = node.level + 1; queue[n - 1] = right; qsort(queue, n, sizeof(Node), cmp); } // 判断是否需要终止搜索 if (queue[0].value + (capacity - queue[0].weight) * (double)queue[0].value / queue[0].weight <= bestValue) { break; } } // 输出最优解 printf("Best value: %d\n", bestValue); printf("Best items: "); for (int i = 0; i < n; i++) { printf("%d ", bestItems[i]); } printf("\n"); // 释放内存 free(queue); free(bestItems); } // 测试 int main() { int n = 5; int capacity = 10; int values[] = {6, 3, 5, 4, 6}; int weights[] = {2, 2, 6, 5, 4}; knapsack(n, capacity, values, weights); return 0; } ``` 该代码使用优先队列来实现分支限界搜索,利用贪心算法对节点进行排序每次取出优先级最高的节点进行扩展。在搜索过程,维护当前最优解,并在搜索结束后输出最优解

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值