C++面向对象程序设计-药品销售统计各种排序方法的实现

【问题描述】
设计一系统,实现医药公司定期对销售各药品的记录进行统计,可按药品的编号、单价、销售量或销售额做出排名。
【实现提示】

  • 在本设计中,首先从数据文件中读出各药品的信息记录,存储在顺序表中。
  • 各药品的信息包括:药品编号、药名、药品单价、销出数量、销售额。
  • 药品编号共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;
	}
}

猜你喜欢

转载自blog.csdn.net/wmrem/article/details/79920209