【问题描述】
设计一系统,实现医药公司定期对销售各药品的记录进行统计,可按药品的编号、单价、销售量或销售额做出排名。
【实现提示】
- 在本设计中,首先从数据文件中读出各药品的信息记录,存储在顺序表中。
- 各药品的信息包括:药品编号、药名、药品单价、销出数量、销售额。
- 药品编号共4位,采用字母和数字混合编号,如:A125,前一位为大写字母,后三位为数字,
- 按药品编号进行排序时,可采用基数排序法。
- 对各药品的单价、销售量或销售额进行排序时,可采用多种排序方法,如直接插入排序、冒泡排序、快速排序,直接选择排序等方法。
- 在本设计中,对单价的排序采用冒泡排序法,
- 对销售量的排序采用快速排序法,
- 对销售额的排序采用堆排序法。
一、代码最终呈现效果
二、药品销售统计记录进行排序的各种排序方法的实现
- 快速排序算法:
int SelectPivot(int left, int right) { return (left + right) / 2; }
int SequenList:: Partition(int left, int right) {
int ll = left;
int rr= right;
DataType d = r[rr];
int tt = r[rr].count;
while (ll != rr) {
while (r[ll].count <= tt && rr > ll)
ll++;
if (ll < rr) {
r[rr]= r[ll];
rr--;
}
while (r[rr].count >= tt &&rr>ll)
rr--;
if (ll < rr) {
r[ll] = r[rr];
ll++;
}
}
r[ll]= d;
return ll;
}
void SequenList::QuickSort(int left, int right) {//销售量快速排序
DataType t;
if (right <= left) return;
int pivot = SelectPivot(left, right);
t= r[right];
r[right] = r[pivot];
r[pivot] = t;
pivot = Partition(left, right);
QuickSort(left, pivot - 1);
QuickSort(pivot + 1, right);
}
- 冒泡排序:
void SequenList::BubbleSort() {
bool noswap;
int i, j;
DataType t;
for (i = 0; i < MaxSize - 1; i++) {
noswap = true;
for (j = MaxSize - 1; j > i;j--)
if (r[j].price < r[j - 1].price) {
t = r[j];
r[j] = r[j - 1];
r[j - 1] = t;
noswap = false;
}
if (noswap)
return;
}
}
- 基数排序:
void SequenList::RadixSort(int d) {
int i, j,k;
int r1 = 10, r2 = 26;
int *ct = new int[r1];
int *nt = new int[r2];
int *a = new int[MaxSize];
int *b = new int[MaxSize];
DataType *cc= new DataType[MaxSize];
int ms = 3;
for (i = 0; i < 3; i++) {
for (j = 0; j < MaxSize; j++) {
a[j] = r[j].num[ms]-'0';
}
for (j = 0; j < r1; j++)
ct[j] = 0;
for (j = 0; j < MaxSize; j++) {
k = a[j];
ct[k]++;
}
for (j = 1; j < r1; j++)
ct[j] = ct[j - 1] + ct[j];
for (j = MaxSize - 1; j >=0; j--) {
k=a[j];
cc[--ct[k]] = r[j];
}
for (j = 0; j < MaxSize; j++)
r[j] = cc[j];
ms--;
}
for (i = 0; i < MaxSize; i++)
cc[i] = r[i];
for (i = 0; i < MaxSize; i++)
b[i] = r[i].num[0]-'A';
for (i = 0; i < r2; i++)
nt[i] = 0;
for (i = 0; i < MaxSize; i++)
nt[b[i]]++;
for (i = 1; i < r2; i++)
nt[i] = nt[i - 1] + nt[i];
for (i = MaxSize - 1; i >= 0; i--)
r[--nt[b[i]]] = cc[i];
delete[]cc;
delete[]nt;
delete[]ct;
delete[]a;
delete[]b;
}
- 大顶堆排序
void SequenList::BigHeapAdjust(float *p, int rr, int len){
float tmp = p[rr];
DataType tt = r[rr];
int j;
for (j = 2 * rr + 1; j <= len - 1; j = 2 * j + 1) //沿节点值较大的儿子往下层筛选,2*r+1是左儿子,2*(r+1)是右儿子
{
if (j<len - 1 && p[j + 1] >= p[j]) //因为j<len-1时,p[j+1]才不会越界?
++j; //如果右儿子大于左儿子,j++转移到右儿子,让j等于左右儿子中较大的那个?
if (tmp >= p[j])
break;
p[rr] = p[j];
r[rr] = r[j];//较大的儿子向父节点平移,并更新r节点的位置
rr= j;
}
p[rr] = tmp;//将根节点放置到最后空出的合适的位置
r[rr] = tt;
}
void SequenList::BigHeapSort(int len)
{
int i, j;
float *p = new float[len],t;
DataType tt;
for (i = 0; i < MaxSize; i++)
p[i] = r[i].count*r[i].price;
//对完全二叉树来说,共len/2个非叶子节点,下标为len/2-1的元素是最后一个非叶子节点
//从最后一个非叶子节点起倒序,用HeapAdjust函数来调整,初建大顶堆,使各个根节点含有最大的key?
for (i = len / 2 - 1; i >= 0; --i)
BigHeapAdjust(p, i, len);
t = p[len - 1];
tt = r[len- 1];
p[len - 1] = p[0];
r[len - 1] = r[0];
p[0] = t;
r[0] = tt;//以上为交换堆顶和堆底,下面开始调整一次,交换一次
for (j = len - 1; j>1; --j)//此处一开始写成了j>0,其实j>1即可;因为j=2时,等HeapAdjust调整完毕并交换后,整个数组已有序?
{
BigHeapAdjust(p, 0, j);
//交换堆顶和堆底?
t = p[j - 1];
tt = r[j - 1];
p[j - 1] = p[0];
r[j - 1] = r[0];
p[0] = t;
r[0] = tt;
}
}