1.1.1 翻转算法
1.逆序数组
2.在顺序表A[m+n]中有A1[m]和A2[n],将A2放在A1前。
先全部逆序,再分别逆序前n个和后m个。
ps:思考将顺序表中的元素左移P个位置,方法同上。
1.1.2 排列组合
1.输出从n个数中取出所有k 个数的所有组合(k<=n)
//A为原始数组
//start为遍历起始位置
//result保存结果,为一维数组
//count为result数组的索引值,起辅助作用
//k为要选取的元素个数
//n为原始数组的长度,为定值
void combine(int* A, int start, int* result, int count, const int k, const int n)
{
int i=0;
for (i=start;i<n+1-count;i++)
{
result[count-1]=i;
if (count-1==0) //输出结果
{
int j;
for (j=k-1;j>=0;j--)
printf("%d\t",A[result[j]]);
printf("\n");
}
else
combine(A,i+1,result,count-1,k,n);
}
}
2.给定一个整数数组b[0..N-1],b中连续的相等元素构成的子序列称为平台。试设计算法,求出b中最长平台的长度。
void Platform (int b[ ], int N)
//求具有N个元素的整型数组b中最长平台的长度。
{
l=1;k=0;j=0;i=0;
while(i<n-1)
{
while(i<n-1 && b[i]==b[i+1])
i++;
if(i-j+1>l)
{
l=i-j+1;
k=j;
} //局部最长平台
i++;
j=i;
} //新平台起点
printf(“最长平台长度%d,在b数组中起始下标为%d”,l,k);
}
3.若S是n个元素的集合,则S的幂集P(S)定义为S所有子集的集合。例如,S=(a,b,c),P(S)={() ,(a),(b),(c),(a,b),(a,c),(b,c),(a,b,c)}给定S,写一递归算法求P(S)。
void comb(int S[],int n,int P[],int i,int k)
//从集合(1..n)中选取k(k<=n)个元素的所有组合
{
if (k==0) printf(P);
else if(k<=n)
{
P[i]=S[i];
comb(P,i+1,k-1); comb(P,i+1,k);
}
}
void allSets(int S[],int n)
{
int i;
int P[maxsize];
for(i=0;i<=n;i++)
{
comb(S,n,P,1,i);
}
}
3.有n个元素放在数组A中,输出这些元素的全排列(递归)。
void perm(int A[],int p,int q)
{
int i,j;
int temp;
if(p==q)
{
printf(A[p]);
}
else
{
for(i=p;i<=q;i++)
{
temp = A[i];
A[i] = A[p];
A[p] = temp;
perm(A,P+1,q);
temp = A[i];
A[i] = A[p];
A[p] = temp;
}
}
}
1.1.3 数量问题
1.找到顺序表中的元素,个数
(1)依次扫描每个数,将扫描的数放入c中,若下一个数与c相同,则count++,否则count--,当count==0时,将遇到的下一个元素放入c中,count=1,继续。
(2)再扫描一次数组,若c出现的次数大于n/2则为主元素。
1.1.4 判断问题
1.给定一个整数数组,你需要寻找一个连续的子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。
解:两个标志,一个记录第一次出现非升序的下标,另一个记录最后一次非升序的下标。
1.1.5 排序问题
1.设任意n个整数存放于数组A(1:n)中,试编写程序,将所有正数排在所有负数前面
void Arrange(int A[],int n)
//n个整数存于数组A中,本算法将数组中所有正数排在所有负数的前面
{
int i=0,j=n-1,x; //用类C编写,数组下标从0开始
while(i<j)
{
while(i<j && A[i]>0)
i++;
while(i<j && A[j]<0)
j--;
if(i<j)
{
x=A[i];
A[i++]=A[j];
A[j--]=x;
}//交换A[i] 与A[j]
}
}
2.设计一个算法,把整数数组中所有的偶数放到所有的奇数之前。要求时间、空间效率尽可能高。
将上题中判定正数(A[i]>0)改为判偶数(A[i]%2==0),将判负数(A[j]<0)改为(A[j]%2!=0)
3.设计算法将数组A[1..n]调整为左右两部分,使的左边所有的元素小于右边的所有元素,并给出这一划分的分界位置。
利用快速排序思想一趟划分
int Partition(int A[],int n)
//将n个元素的数组A调整为左右两部分,且左边所有元素小于右边所有元素,返回分界位置。
{
int i=0,j=n-1,rp=A[0]; //设数组元素为整型
while(i<j)
{
while(i<j &&A[j]>=rp)
j--;
while(i<j &&A[i]<=rp)
i++;
if(i<j)
{
x=A[i];
A[i]=A[j];
A[j]=x;
}
}
A[i]=rp;
return(i); //分界元素
}
4.用递归算法求出数组中的最大值和最小值。
void MinMaxValue(int A[],int n,int &max,int &min){
if(n>=0){
if(max<A[n])
max=A[n];
if(min>A[n])
min=A[n];
MinMaxValue(A,n-1,max,min);
}
}