惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
S
SegmentFault 最新的问题
Jina AI
Jina AI
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
WordPress大学
WordPress大学
爱范儿
爱范儿
博客园 - Franky
量子位
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网

博客园 - 超薄

符号执行虚假控制流去混淆 ios 重启usb ubuntu 搜狗输入法安装 js 反hook js 源码乱码 js和html加上混淆 js 字体加密 jj混淆 webpack 暴力方式扣取 志远js调试相关 并行算法中的异常 事件模式实现通知 扩展属性应用 位运算应用口诀和实例(转自大笨狼) 数据结构Tire 树实际应用----过滤禁词 动态规划 快速排序算法 字典 DictionaryBase 和 SortedList 模式匹配文本处理 位运算
数据结构实际应用----订单排序(堆排序求前N大)
超薄 · 2012-02-15 · via 博客园 - 超薄

1.堆排序思想
堆排序是一种树形选择排序,在排序过程中,将A[1..n]看成是完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。
2.堆的定义:n个元素的序列K1,K2,K3,…Kn称为堆,当且仅当该序列满足特性:Ki≤K2i , Ki ≤K2i+1(1≤i≤n/2)
堆实质上是满足如下性质的完全二叉树:树中任一非叶子结点的关键字均大于等于其孩子结点的关键字。例如序列{1,35,14,60,61,45,15,81}就是一个堆,它对应的完全二叉树如下图1所示。这种堆中根结点(称为堆顶)的关键字最小,我们把它称为小根堆。反之,若完全二叉树中任一非叶子结点的关键字均大于等于其孩子的关键字,则称之为大根堆。

    

 下面的例子用大根堆来实现订单排序

 思路是保持前K大有序,然后插入时候判断,非大不插,并且插入的时候是二分查找位置,弹出最后一个

订单结构

  public struct Order:IComparable<Order>
{
public DateTime CreateTime;
public string Name;
public decimal Total;
public int OrderDetailCount;
private static IComparer<Order> _compare;
public Order(string name,DateTime createTime,decimal total,int orderdetailCocunt)
{
Name = name;
CreateTime = createTime;
Total = total;
OrderDetailCount = orderdetailCocunt;
}

public int CompareTo(Order other)
{
return string.Compare(Name, other.Name);
}
public static IComparer<Order> SortByTime()
{
return new TimeCompare();
}
public static IComparer<Order> SortByTotal()
{
return new TotalComare();
}
public static IComparer<Order> SortByOrderDetail()
{
return new OrderDetailCompare();
}
public static bool operator >=(Order left,Order right)
{
return left.CompareTo(right)>=0;
}
public static bool operator <=(Order left, Order right)
{
return left.CompareTo(right) <= 0;
}
public static bool operator >(Order left, Order right)
{
return left.CompareTo(right) > 0;
}
public static bool operator<(Order left, Order right)
{
return left.CompareTo(right) <0;
}

}

   public  class TimeCompare : IComparer<Order>
        {

            public int Compare(Order x, Order y)
            {
                return x.CreateTime.CompareTo(x.CreateTime);
            }
        }
        public class TotalComare : IComparer<Order>
      {
          public int Compare(Order x, Order y)
          {
              return x.Total.CompareTo(y.Total);
          }
      }
        public  class OrderDetailCompare : IComparer<Order>
      {

          public int Compare(Order x, Order y)
          {
              return x.OrderDetailCount.CompareTo(y.OrderDetailCount);
          }
      }

 堆排类

 public class HeapSort
{
private int heapSize = 0;
public Order[] Heap;
public int Count = 0;
IComparer<Order> SelfCompare;
public HeapSort(int size,IComparer<Order> compare)
{ heapSize = size;
Heap = new Order[size];
SelfCompare = compare;
}

public void Insert(Order iterm)
{
if (SelfCompare.Compare(iterm, Heap[heapSize - 1]) > 0)
{
Insert(iterm, 0, (Heap.Length - 1) / 2, Heap.Length - 1);
}
Count++;
}

private void Insert(Order iterm, int min, int pos, int max)
{

if ((SelfCompare.Compare(iterm, Heap[pos]) <= 0 && SelfCompare.Compare(iterm,Heap[pos + 1]) >= 0) || pos == 0)
{
for (int i = heapSize - 1; i > pos; i--)
{
Heap[i] = Heap[i - 1];
}
if (pos == 0)
{
Heap[pos] = iterm;
}
else
{
Heap[pos + 1] = iterm;
}
}
else
{
if (iterm.CompareTo(Heap[pos]) > 0)
{
max = pos;
}
else
{
min = pos;
}
pos = Convert.ToInt32((max + min) / 2);
Insert(iterm, min, pos, max);
}
}

}

测试代码

  static void Main(string[] args)
{
HeapSort mySort = new HeapSort(1000,new TimeCompare());
Random Rand = new Random();
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
for (int i = 0; i < 1000 * 1000; i++)
{
Order temporder = new Order("Product"+i, DateTime.Now.AddMinutes(Rand.Next()),i,Rand.Next());
mySort.Insert(temporder);
}
sw.Stop();

Console.WriteLine(sw.ElapsedMilliseconds);

for (int i = 0; i < mySort.Heap.Length; i++)
{
Order iterm = mySort.Heap[i];

Console.WriteLine(iterm.Name);
}
Console.WriteLine("长度:" + mySort.Count + "-------------------------------");
Console.Read();

}

百万订单实际需要30毫秒,时间复杂度 大致可看做o(n).