1、堆和二叉排序树的区别
以大顶堆为例,大顶堆的特点是要求左右孩子的关键字值小于双亲关键字值,对于左右孩子关键字值的大小没有次序规定。
而二叉排序树要求左孩子关键字值小于双亲关键字值,右孩子关键字值大于双亲关键字值,每个双亲结点与左右孩子之间的关键字值有次序关系。
当对两种树执行中序遍历时,二叉排序树会得到一个递增序列,堆不一定能得到有序序列。
2、若只想得到一个序列中第k(k>=5)个最小元素之前的部分排序序列,最好采用什么排序方法?
插入排序、快速排序都需要将所有元素排序之后才能得到前k个最小。
冒泡排序、选择排序、堆排序不需要将所有元素进行排序,因为其每一趟排序都可确定一个元素的最终位置。
堆排序初始建堆的时间不超过4n,得到序列的时间是klog2n,而冒泡排序和选择排序所需时间是kn,所以选择堆排序。
3、有n个元素构成一个小顶堆,增加一个新元素K,调整为一个堆
将K插入数组的第n+1个位置,作为叶子结点插入堆中,比较其与父节点的大小,若关键字值大于父节点关键字值,则停止比较,若小于,则将其与其父节点交换,继续比较其与其新父节点的关键字值,直到它已成为根或大于父节点的值。
4、编写一个算法,在基于单链表表示的待排序关键字序列上,进行简单选择排序
typedef struct node
{
ELemType data;
struct node *next;
} Node;
void f(Node head)
{
Node *p, *q, *qf, *qm, *qmf; //q遍历指针,qf跟随q,随时指向q的前一个结点,qm指向当前q所找到的最小结点
//qmf跟随qm,在qm=q时,qmf = qf
p = qf = qm = qmf = head;
q = head->next;
int minn = q->data;
while(p)
{
int flag = 0;
if(!p->next) break;
q = p->next;
qf = qm = qmf = p;
minn = q->data;
while(q)
{
if(q->data < minn)
{
flag = 1; //本轮有需要调整的地方
minn = q->data;
qm = q;
qmf = qf;
}
if(q->next)
{
qf = q;
q = q->next;
}
else break;
}
if(flag) //如果flag为0,本轮就没有需要调整的地方了
{
qmf->next = qm->next;
qm->next = p->next;
p->next = qm;
}
p = qm; //但是这里都要执行必须要让p前移一个
}
}
看答案怎么就那么几行。。。我怎么写了这么多。。。
5、设计一个算法,判断一个数据序列是否构成一个小根堆
bool judge(int a[], int n)
{
int i;
for(i = 1; i <= n/2; i++)
{
if(a[i] > a[i*2] || (i*2+1 <= n && a[i] > a[i*2+1]))
{
return false;
}
}
return true;
}
就离谱,答案怎么那么多,我就写了几行
写的挺对的吧,就是没倒着来,但是这里又不是建堆,只是判断,找到一个不符合的不就行了吗