您的位置:首页 > 理论基础 > 数据结构算法

数据结构实际应用----订单排序(堆排序求前N大)

2012-02-15 14:06 477 查看
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).
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: