数据结构算法题1
- 设计程序按从大到小的次序依次输出函数f(a,b)=2*a2+b2的最小的100个函数值及相应的两个参数的值,其中a和b均为自然数。(难易度85)
要求:
(1).作为函数值的存储结构应尽可能节省空间。
(2).所设计算法及整个程序的时间复杂度应尽可能小。
#include <stdio.h>
#include<stdlib.h>
#define MAX 100
typedef struct Node//定义节点的结构
{
int data;//数据
int a;
int b;
}Node;
int f(int a,int b)//函数计算
{
return 2*a*a+b*b;
}
void swap(Node *a,Node *b)//交换元素
{
Node temp=*a;
*a=*b;
*b=temp;
}
//调整为大根堆
void heapify(Node heap[],int size,int i)
{
int left=2*i+1;
int right=2*i+2;
int large=i;
if(left<size && heap[left].data>heap[large].data)//如果左孩子比节点大
large=left;//更新最大下标
if(right<size && heap[right].data>heap[large].data)//如果右孩子比节点大
large=right;//更新
if(i!=large)//如果更新了,调整
{
swap(&heap[i],&heap[large]);
heapify(heap,size,large);//递归调整
}
}
void heapSort(Node heap[], int size) //堆排序,每次将堆顶与最后一个元素交换,每次元素个数--
{
for (int i = size - 1; i > 0; i--)
{
swap(&heap[0], &heap[i]);
heapify(heap, i, 0);//交换过后继续调整为大根堆
}
}
int main()
{
Node heap[MAX];
int size = 0;
for (int i = 0; ; i++)
{ // 没有固定的终止条件
for (int j = 0; ; j++)
{ // 没有固定的终止条件
int data = f(i, j);
if (size < MAX)
{
heap[size].data = data;
heap[size].a = i;
heap[size].b = j;
size++;
if (size == MAX)
{
//MAX/2-1为最后一个非叶子节点
for (int k = MAX / 2 - 1; k >= 0; k--)
{
heapify(heap, size, k);
}
}
} else if (data < heap[0].data) //有比堆顶元素小的,将堆顶换出去
{
heap[0].data = data;
heap[0].a = i;
heap[0].b = j;
heapify(heap, size, 0);
}
// 提前退出条件
if (size == MAX && data > heap[0].data) //已经存了所需个数,且数据比堆顶还大,后面数据只会越来越大,直接终止循环
{
break;
}
}
// 提前退出条件
if (size == MAX && f(i, 0) > heap[0].data) //此时f(i,0)为函数i变化时的最小值,比最大值还大,所以提前退出
{
break;
}
}
heapSort(heap, size);//调用堆排序
int m=100;
for (int i = MAX - 1; i >= 0; i--) //从大到小的次序依次输出
{
printf("%d %d: a=%d, b=%d\n",m--, heap[i].data, heap[i].a, heap[i].b);
}
return 0;
}