8-1(比较排序的概率下界) 在这一问题中,我们将证明对于给定的n个互异的输入元素,任何确定或随机的比较排序算法,其概率运行时间都有下界Ω(nlgn)。首先分析一个确定的比较排序算法A,其决策树为Ta,假设A的输入的每一种排列情况都是等可能的。
a) 假设Ta的每个叶子结点都标有在给定的随机输入情况下到达该结点的概率。证明:恰有n!个叶子结点标有1/n!,其他的叶结点标记为0.
因为对于n个元素有n!种可能数组元素排列,那么由此对应于决策树的n!个叶子结点,对于n!个叶子结点中的每一个叶子结点对应一种排序情况,因为假设每一种排列情况都是等可能的,所以到达每一个叶子结点的概率1/n!,对于决策树来说,我们只考虑这n!个叶子结点。其他叶子结点不属于这n!种排序情况,所以随机输入排序情况到达该结点的概率是0.
b)定义D(T)表示一颗决策树T的外部路径长度,即D(T)是T的所有叶结点深度的和,假设T为一颗有k>1个叶结点的决策树,LT和RT分别是T的左子树和右子树。证明:D(T)=D(LT)+D(RT)+k.
c)定义d(k)为所有具有k>1叶结点的决策树T的最小D(T)值。证明:d(k)=min{d(i)+d(k-i)+k}.
d)证明:d对于给定的k(k>1)和i(1<i<k-1),函数ilgi+(k-i)lg(k-i)在i=k/2处取得最小值,并有结论d(k)=Ω(klgk).
e)证明:D(Ta)=Ωm(n!lgn!),并得出在平均情况下,排序n个元素的时间代价Ω(nlgn)
f) 不太懂。
8-2 (线性时间原址排序) 假设有一个包含n个待排序数据记录的数组,且每条记录的关键字的值为0或1,对这样一组记录进行排序的算法可能具备如下三种特性中的一部分。
1,算法的时间代价是O(n).
2,算法是稳定的。
3,算法是原址排序,除了输入数组之外,算法只需要固定的额外存储空间。
a,给出满足1和2的算法
计数排序
b,给出满足1和3的算法
既然n个数只有0和1两种值,那么可以按照我设计的算法,满足线性时间,不需要辅助空间,但是不稳定。
#include <iostream>
#include <time.h>
using namespace std;
void _8_2_b(int A[],int n)
{
int k=0;
for (int i=0;i<n;i++)
{
if (A[i]==0)
{
k++;
}
}
for (int j=0;j<n;j++)
{
if (j<=k)
{
A[j]=0;
}
else
{
A[j]=1;
}
}
}
void main()
{
const n=100;
int A[n]={0};
srand( (unsigned)time( NULL ) );
for (int i=0;i<n;i++)
{
A[i]=rand()%2;
}
_8_2_b(A,n);
for ( i=0;i<n;i++)
{
cout<<A[i]<<" ";
}
}
c,给出满足2和3的算法
插入排序
d 你设计的算法a-c中的任一个是否可以用于RADIX-SORT的第2行作为基础排序方法,从而使RADIX-SORT在排序有b位关键字的n条记录时的时间代价是O(bn)?如果可以,请解释应如何处理,如果不行,请说明原因。
(a)可以。用计数排序作为基数排序的子程序即可。
(b)不可以。我设计的这个程序,只是在特定情况下可以排序,不具备普遍性。
(c)不可以。插入排序属于比较排序算法,所以其时间下界是Ω(nlgn)。没有达到O(bn).
e.假设有n条记录,其中所有关键字的值都在1到k的区间内,你应该如何修改计数排序,使得它可以在O(n+k)时间内完成对n条记录的原址排序。除输入数组外,你可以O(k)使用大小的额外存储空间。你给出的算法是稳定的吗?
不稳定。以下是具体算法:
//此算法也是对计数排序的一种改进,这里有以下3点改进。
//1.只需要计算等于A[i]的元素,不用添加循环用来计算小于A[i]的元素
//2.同时也不用添加辅助数组B来对数组A进行输出,只需要在原来的A数组上进行排序就可以了。
//3.对于含有重复数据的数组进行排序时,用于存放数据出现次数的数组C的长度是刨去重复数据的最小值k,但是对于重复数据的处理是不稳定的。
//但是我还在思考这个排序是否是原址的计数排序?懂的请留言和我交流下哦,谢谢!
#include <iostream>
#include <time.h>
using namespace std;
const n=20;
void COUNTING_SORT(int A[n])
{
int max=A[0],min=A[0];
for (int i=0;i<n;i++)
{
if (A[i]>max)
{
max=A[i];
}
if (A[i]<min)
{
min=A[i];
}
}
int k=max-min+1;
int *C=new int[k+1];
for ( i=0;i<=k;i++)
{
C[i]=0;
}
for (int j=0;j<n;j++)
{
C[A[j]-min+1]++;
}
for (j=n-1;j>=0;)
{
k=max-min+1;
if(C[k]!=0)
{
A[j]=max;
C[k]--;j--;
}
else
{
max--;
}
}
}
void main()
{
int A[n]={0};
srand( (unsigned)time( NULL ) );
for (int i=0;i<n;i++)
{
A[i]=rand()%100;
}
COUNTING_SORT(A);
for (int j=0;j<n;j++)
{
cout<<A[j]<<" ";
}
}
8-3 (变长数据项的排序)
a.给定一个整数数组,其中不同的整数所包含的的数字的位数可能不同,但该数组中,所有整数中包含的总数字位数为n.设计一个算法,使其可以在O(n)时间内对该数组进行排序。