【求助】算法导论9.3线性时间查找算法

haofang666777 2012-02-24 12:12:34
结果与错误,程序也是非正常结束的;
请大侠帮忙修改

#include<iostream>
#include<ctime>
#include<iterator>
using namespace std;

int random(int p,int q)
{
time_t t;
srand((unsigned)time(&t));
return rand()%(q-p)+p;
}
int mid(int L,int R)
{
return L+(R-L)/2;
}
void swap(int &a,int&b)
{
int temp=a;
a=b;
b=temp;
}
void randomshuffle(int A[],int L,int R)
{
for(int i=L;i<R;i++)
{
int j=random(i,R);
swap(A[i],A[j]);
}
}
void insertsort(int A[],int L,int R)
{
for(int i=L+1;i<=R;i++)
{
int value=A[i];
int j=i-1;
while(j>=L&&A[j]>value)
{
A[j+1]=A[j];
j--;
}
A[j+1]=value;
}
}
int partition(int A[],int L,int R,int key)
{
//轴值的首尾标志
int leftIndex = L;
int rightIndex = R;

//快速排序的一轮
while (leftIndex < rightIndex)
{
//从右侧开始扫描若右侧数大于轴值则右侧标志位-1
while (leftIndex < rightIndex && A[rightIndex] > key)
{
rightIndex--;
}
//若右侧数小于轴值则交换右侧的数和左侧leftindex所指的数 并从左边开始比较
while (leftIndex < rightIndex && A[rightIndex] < key)
{
swap(A[leftIndex], A[rightIndex]);
leftIndex++;
}
//从左边开始比较若该数小于或等于轴值 则左侧标志位+1 注意一定要注意等于的情况
while (leftIndex < rightIndex && (A[leftIndex] < key || A[leftIndex] == key))
{
leftIndex++;
}
//从左边开始比较若该数比轴值大 则将该数和右侧标志位rightIndex对应的值交换并从右侧开始计算
while (leftIndex < rightIndex && A[leftIndex] > key)
{
swap(A[leftIndex], A[rightIndex]);
rightIndex--;
}
if (leftIndex >= rightIndex)
{
break;
}
}
//求key值对应的索引
return leftIndex;
}
int selete(int A[],int L,int R,int i)
{
if(R-L<5)
{
insertsort(A,L,R);
//cout<<A[L+i-1]<<"***";
return A[L+i-1];
}
int length=R-L+1;
int size=length/5,left,right;
for(int k=0;k<size;k++)
{
//计算每一组的起始索引
left=L+k*5;
//计算每一组的终止索引
right=left+4;
insertsort(A,left,right);
swap(A[L+k],A[left+2]);
}
//求中位数的中位数x
int x=selete(A,L,L+size-1,(size+1)/2);
//将数组分割成两组 返回该pivot的索引值
int M=partition(A,L,R,x);
int K=M-L+1;
//在前半部分 递归前部分
if(i<=K)
{
return selete(A,L,M,i);
}
else//在后半部分递归
{
return selete(A,M+1,R,i-K);
}
}
int main()
{
int A[100];
int i;
for(i=0;i<100;++i)
A[i] = i+1;
randomshuffle(A,0,99);//随机排列,打乱顺序

cout<<"Init A:\n";
copy(A,A+100,ostream_iterator<int>(cout," "));
cout<<endl;

for(i=0;i<100;++i)
{
cout<<i<<" th element: ";
cout<<selete(A,1,100,i)<<endl;
}
cout<<endl;
}
...全文
125 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
面包大师 2012-02-24
  • 打赏
  • 举报
回复
当size=4(偶数),L+size-1=3,总共有4个数,中位数按定义是第2个最小的,而(size-1)/2=1,楼主把下标和第几个最小的数搞混了。。。我们从来没有这种说法:第0个最小的数
面包大师 2012-02-24
  • 打赏
  • 举报
回复
int x=selete(A,L,L+size-1,(size+1)/2);//第一次调用这个的时候,L=0;假设size=5(奇数),那么L+size-1=4,那么总共有五个数,那么就应该是找第三小的数,而(size-1)/2=2
面包大师 2012-02-24
  • 打赏
  • 举报
回复
int main()
{
for(i=1;i<=100;++i)//是因为这儿,从0开始是错误的,只能说是第一个最小的数,不能说第0个最小的
{
cout<<i<<" th element: ";
cout<<selete(A,0,99,i)<<endl;
}
cout<<endl;
}
haofang666777 2012-02-24
  • 打赏
  • 举报
回复
还有以下疑问
(1)selete中的递归调用找中位数,为什么是(size+1)/2而不是(size-1)/2;而我计数的角标是从0开始的
int x=selete(A,L,L+size-1,(size+1)/2);
haofang666777 2012-02-24
  • 打赏
  • 举报
回复
谢谢 ,完整程序 奉上,
您辛苦了

#include<iostream>
#include<ctime>
#include<iterator>
using namespace std;

int random(int p,int q)
{
time_t t;
srand((unsigned)time(&t));
return rand()%(q-p)+p;
}
int mid(int L,int R)
{
return L+(R-L)/2;
}
void swap(int &a,int&b)
{
int temp=a;
a=b;
b=temp;
}
void randomshuffle(int A[],int L,int R)
{
for(int i=L;i<R;i++)
{
int j=random(i,R);
swap(A[i],A[j]);
}
}
void insertsort(int A[],int L,int R)
{
for(int i=L+1;i<=R;i++)
{
int value=A[i];
int j=i-1;
while(j>=L&&A[j]>value)
{
A[j+1]=A[j];
j--;
}
A[j+1]=value;
}
}
int partition(int A[],int L,int R,int key)
{
//轴值的首尾标志
int leftIndex = L;
int rightIndex = R;

//快速排序的一轮
while (leftIndex < rightIndex)
{
//从右侧开始扫描若右侧数大于轴值则右侧标志位-1
while (leftIndex < rightIndex && A[rightIndex] > key)
{
rightIndex--;
}
//若右侧数小于轴值则交换右侧的数和左侧leftindex所指的数 并从左边开始比较
while (leftIndex < rightIndex && A[rightIndex] < key)
{
swap(A[leftIndex], A[rightIndex]);
leftIndex++;
}
//从左边开始比较若该数小于或等于轴值 则左侧标志位+1 注意一定要注意等于的情况
while (leftIndex < rightIndex && (A[leftIndex] < key || A[leftIndex] == key))
{
leftIndex++;
}
//从左边开始比较若该数比轴值大 则将该数和右侧标志位rightIndex对应的值交换并从右侧开始计算
while (leftIndex < rightIndex && A[leftIndex] > key)
{
swap(A[leftIndex], A[rightIndex]);
rightIndex--;
}
if (leftIndex >= rightIndex)
{
break;
}
}
//求key值对应的索引
return leftIndex;
}
int selete(int A[],int L,int R,int i)
{
if(R-L<5)
{
insertsort(A,L,R);
//cout<<A[L+i-1]<<"***";
return A[L+i-1];
}
int length=R-L+1;
int size=length/5,left,right;
for(int k=0;k<size;k++)
{
//计算每一组的起始索引
left=L+k*5;
//计算每一组的终止索引
right=left+4;
insertsort(A,left,right);
swap(A[L+k],A[left+2]);
}
//求中位数的中位数x
int x=selete(A,L,L+size-1,(size+1)/2);
//将数组分割成两组 返回该pivot的索引值
int M=partition(A,L,R,x);
int K=M-L+1;
//在前半部分 递归前部分
if(i<=K)
{
return selete(A,L,M,i);
}
else//在后半部分递归
{
return selete(A,M+1,R,i-K);
}
}
int main()
{
int A[100];
int i;
for(i=0;i<100;++i)
A[i] = i+1;
randomshuffle(A,0,99);//随机排列,打乱顺序

cout<<"Init A:\n";
copy(A,A+100,ostream_iterator<int>(cout," "));
cout<<endl;

for(i=1;i<=100;++i)
{
cout<<i<<" th element: ";
cout<<selete(A,0,99,i)<<endl;
}
cout<<endl;
}

64,318

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧